8

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?

halfer
  • 19,824
  • 17
  • 99
  • 186
user2050342
  • 93
  • 1
  • 5

2 Answers2

11

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

Ryan Gregg
  • 2,015
  • 13
  • 16
3

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.

Coder12345
  • 3,431
  • 3
  • 33
  • 73