OneDrive for Business API: What is the Client Secret for a native app? - onedrive

According to the API doc, after you get an auth code in step 1 you need to redeem it for a token, using the following parameters:
client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}
&code={code}&grant_type=authorization_code&resource={resource_id}
But where do I get the client_secret value from? This is a native client app that I registered in Azure AD, so it only has a Client ID and a Redirect URI.

For a native client app, you don't need to provide the client_secret value when redeeming the authorization code or refresh token. Only "confidential" clients, aka services, need to provide the client_secret.

Related

Oauth2: Authenticate single page app without client secret when secret is required by service

I would like to create an integration with quire.io, which currently only supports the Oauth2 authorization_code flow with client_secret.
This causes me a problem because my application will need a dashboard so users can configure it.
So far I have been trying to get a token on a backend server (which has the secret) and then send the token to the client in a cookie as a JWT.
Is there a way I can securely access the quire api from my frontend?
The authorization_code flow without client secret hasn't been implemented yet (different priorities).
For now you'll need the extra server to keep the client_secret in a secure place.

React Native OAuth2 and REST API authentication flow

I'm having a bit trouble understanding this predicament a REST API supporting React Native (Mobile App) with OAuth2 authentication.
I've managed to setup the OAuth2 flow and can login via OAuth2 provider. This communication is still just between the Mobile App and the 3rd party OAuth2 provider. How can I use those tokens I've obtained (and actually trust the request) to create an account in my REST API so that the server can actually generate a JWT token that will be used for future requests?
Can't seem to find an answer to this question. Would love some help with this one
Ok, I've managed to figure this one out.
To achieve what I want the Client (in this case mobile app) does the authentication flow and will receive an access_token and a refresh_token along with an id_token. The last one (id_token) contains the info about the user which the app should send to my REST API. Once the server receives it it will make an HTTP request to Google (my OAuth2 Provider) to verify that this token is in fact a valid one and issued by them.
After that I just create an account and issue my own token in response to the Mobile's App request.
It's explained here in Google Docs
Most likely all the major identity providers would follow along this path. Or, at least I'm hoping they do.

Retrieve user access TOKEN from WSO2 Api Manager

I have a problem with retrieving the end-user access token from wso2, I need it to invoke the API that retrieves the list of all applications in the Wso2 Api Manager Store. I did a research on this site:
https://docs.wso2.com/display/AM210/apidocs/store/#!/operations#ApplicationCollection#applicationsGet,
but I don't know how I can generate user token (not application token).
On the other side I found the temporary solution, that returns a list of all applications invoking the API login, and then API that returns the app list found on this link: https://docs.wso2.com/display/AM210/Store+APIs, but it shows me only how to do it with a session authentication, NOT with JWT token auth.
thanks in advance.
Please follow the getting started guide[1]. For a token generation, you need client id and secret. To get that you need to register an application.
[1] - https://docs.wso2.com/display/AM210/apidocs/store/#guide

How to secure Web API with Auth0 without exposing ClientId & ClientSecret to client?

I am creating a new .Net Core Web API that is consumed by a new React client-side app. Both the client-side app and the Web API are on different hosts and protected by Auth0. I set up both the client-side app and the Web API in Auth0, and then I created a machine-to-machine app in Auth0 to be able to communicate with the Web API silently (without a user interface). The security flow works like this:
User tries to access client-side app.
User is re-directed to Auth0 to provide credentials.
Auth0 authenticates the credentials and returns user info (including user ID + access token) to client-side app.
Client-side app stores user info in local storage for future use until it expires.
Any calls to 3rd party APIs are routed through my own Web API, so 3rd party API keys are sitting in a safe place on the server, not on the client-side.
User accesses a page that requires a call to my Web API but we don't have an access token for my Web API yet.
Client-side app reads the ClientId & ClientSecret (hard-coded values) from .env file and makes a POST request to Auth0 to fetch an access token for my Web API (this is Auth0's recommended way of getting the access token for the Web API silently except they don't specify where the ClientId & ClientSecret would be stored).
Auth0 returns an access token for my Web API.
Client-side app stores the Web API access token in local storage for future use until it expires.
Client-side app invokes my Web API with newly acquired access token as the bearer token in the header.
Web API receives the access token, authenticates with Auth0 and fulfills the request.
All of the above is working for me but I am concerned about storing the Auth0 ClientSecret of my Web API in the client-side app. Although it is not visible on the screen or in a cookie anywhere, any capable user would be able to get at it by inspecting the network traffic.
Many people on the Internet seem to be fine with storing 3rd party API keys in .env files while others advise routing 3rd party API access through your own Web API ... and I am doing the latter. But I still need the Auth0 ClientSecret to get to my own Web API and I cannot figure out a better place way to get to it without storing them somewhere on the client-side.
One last-ditch solution I can think of is to not protect my Web API through Auth0 and instead every call from the client-side app to my Web API should include something unique (like the user ID from Auth0) that can be validated by the Web API. Thankfully, the user ID from Auth0 will be stored in our database when the user is set up initially, so this is actually possible.
Does Auth0 have any other way for me to get the Web API access token without providing the ClientSecret given that I already have the client-side app's access token? I am curious to know how others have secured both their client-side app and their Web API through Auth0.
You are correct, you should not include the client secret in your client-side app. Do not use a client credentials flow, instead use a auth code + PKCE or implicit flow.
With that being said, Auth0 should handle most of that if you are using a library or SDK.
You have two options for getting the token:
When requesting the initial access token and ID token add the Web API as an audience and request the related scopes.
Make a silent request using the checkSession function for Auth0.js or getTokenSilently for auth0-spa-js
Take a look at this:
https://auth0.com/docs/architecture-scenarios/spa-api/part-3

Error: Public clients can't send a client secret while try to get access token in Onedrive

I am trying to get OneDrive access token by following URL
https://login.live.com/oauth20_token.srf?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&redirect_uri=https://login.live.com/oauth20_desktop.srf&code=AUTHORIZATION_CODE&grant_type=authorization_code
but the response is as following
{"error":"invalid_request","error_description":"Public clients can't send a client secret."}
Can anyone explain this?
A "public client" is a mobile or desktop application (web services are "confidential clients"). MSA is giving you this response because you're redirecting to https://login.live.com/oauth20_desktop.srf. In this case, you should not be providing the client_secret value in the request, so your request should just look like this:
https://login.live.com/oauth20_token.srf?client_id=YOUR_CLIENT_ID&redirect_uri=https://login.live.com/oauth20_desktop.srf&code=AUTHORIZATION_CODE&grant_type=authorization_code
A more recent example from:
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
Request an access token with a client_secret
Now that you've acquired an authorization_code and have been granted permission by the user, you can redeem the code for an access_token to the resource. Redeem the code by sending a POST request to the /token endpoint:
// Line breaks for legibility only
POST /{tenant}/oauth2/v2.0/token HTTP/1.1 Host:
https://login.microsoftonline.com Content-Type:
application/x-www-form-urlencoded
client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=https%3A%2F%2Fgraph.microsoft.com%2Fmail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&code_verifier=ThisIsntRandomButItNeedsToBe43CharactersLong
&client_secret=JqQX2PNo9bpM0uEihUPzyrh // NOTE: Only required for web apps. This secret needs to be URL-Encoded.
Parameter
Required/optional
Description
tenant
required
The {tenant} value in the path of the request can be used to control who can sign into the application. Valid values are common, organizations, consumers, and tenant identifiers. For more information, see Endpoints.
client_id
required
The Application (client) ID that the Azure portal – App registrations page assigned to your app.
scope
optional
A space-separated list of scopes. The scopes must all be from a single resource, along with OIDC scopes (profile, openid, email). For more information, see Permissions and consent in the Microsoft identity platform. This parameter is a Microsoft extension to the authorization code flow, intended to allow apps to declare the resource they want the token for during token redemption.
code
required
The authorization_code that you acquired in the first leg of the flow.
redirect_uri
required
The same redirect_uri value that was used to acquire the authorization_code.
grant_type
required
Must be authorization_code for the authorization code flow.
code_verifier
recommended
The same code_verifier that was used to obtain the authorization_code. Required if PKCE was used in the authorization code grant request. For more information, see the PKCE RFC.
client_secret
required for confidential web apps
The application secret that you created in the app registration portal for your app. Don't use the application secret in a native app or single page app because a client_secret can't be reliably stored on devices or web pages. It's required for web apps and web APIs, which can store the client_secret securely on the server side. Like all parameters here, the client secret must be URL-encoded before being sent. This step is usually done by the SDK. For more information on URI encoding, see the URI Generic Syntax specification. The Basic auth pattern of instead providing credentials in the Authorization header, per RFC 6749 is also supported.
So, if creating a desktop or mobile app and if you registered your app as such in the Azure portal at https://portal.azure.com/ then if you send client_secret you would get that particular error. So you must remove it from the POST request to successfully exchange received code for authentication token and refresh token. Note that confidential web app is the only type which requires to send client_secret. Other types of registered apps or public apps should not send the client_secret.
The code is valid for 10 minutes so it must be immediately exchanged for authentication token using the request similar to the above.
Note one more thing:
Whether or not you'll need to send a client_secret depends whether or not you've registered your application in AzureAD as "web" (requires sending client_secret) or "native app" (does not require sending the client_secret). So your implementation will depend on the registration you did. You can change the type of application in AzureAD -> App Registrations -> select Authentication from the left menu. Under the Platform Configurations choose your specific platform.