0

I have API and SPA at same azure. I already set the Expose an API and gave permission on my SPA. but when I login on my SPA the return token that I pass to my API is not authorized.

any thing else I need to do into my SPA?

I use React js and MSAL to login.

Mer Merced
  • 33
  • 7

1 Answers1

0

You may miss the scope. The scope is format as api://{client_id}/.default.

There is a sample using the on-behalf-of flow: https://github.com/Azure-Samples/ms-identity-javascript-react-spa-dotnetcore-webapi-obo

In ProfileSPA/src/utils/authConfig.js:

export const apiConfig = {
    resourceUri: "https://localhost:44351/api/profile",
    resourceScopes: ["Enter the API scopes as declared in the app registration 'Expose an Api' blade in the form of 'api://{client_id}/.default'"]
}

https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow#use-the-access-token-to-access-the-secured-resource

enter image description here

unknown
  • 6,778
  • 1
  • 5
  • 14
  • with regards on the scope format: api://ClientId/Local_API_Access. I follow the linked you shared but still the same issue. – Mer Merced Mar 23 '21 at 05:53
  • @StillANoob Could you share the details of your error? just 403? – unknown Mar 23 '21 at 06:29
  • Just 401, Uncaught (in promise) Error: Request failed with status code 401 – Mer Merced Mar 23 '21 at 06:35
  • I'm successfully log in, but the token return from MSAL is not authorize to access my API. – Mer Merced Mar 23 '21 at 06:47
  • Which step did you face the error, hit **Accept**? – unknown Mar 23 '21 at 07:20
  • I encounter the 401 when I'm trying to access the API I registered in Azure. during the API call and passing the Token. – Mer Merced Mar 23 '21 at 07:43
  • But when i use token from this code, it works. var clientId = "MyClientId"; var clientSecret = "APIClientSecret"; var adCred = new ClientCredential(clientId, clientSecret); var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/TenantId"); var token = await authenticationContext.AcquireTokenAsync(clientId, adCred); var accesstoken = token.AccessToken; – Mer Merced Mar 23 '21 at 07:46
  • Try to see the diagram in my reply. If you mean to just get the access token for API, you don't need to call with obo flow. You could use auth code flow or implicit flow. But you use client credentials flow(ClientCredential) in your comment, which is based on applications without users. – unknown Mar 23 '21 at 07:56
  • Base on the diagram, I can't use the Token A to access the web API B? I need to request a new token providing client secret and client Id like my code above? – Mer Merced Mar 23 '21 at 07:57
  • You can't use the Token A to access the web API B. In obo flow, we get token B following [this](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow#example), and assertion is the token A. – unknown Mar 23 '21 at 08:02
  • And there are the [steps](https://stackoverflow.com/a/65608406/13308381) of on-behalf-of flow using Postman. Web API A is API in yours, Web API B is SPA in yours. It may help you understand. – unknown Mar 23 '21 at 08:05
  • My process is, I login on SPA using Azure AD Authentication (MSAL). then the MSAL will return Access token and other information. Then im going to use the token from SPA to access the API which is in the same Azure. I'm expecting that since I already gave my SPA a permission on Expose API(Scope) of my API. the token return when i login on SPA has authorization to access the API. – Mer Merced Mar 23 '21 at 08:20
  • As you said that you've exposed an api and add the api permission to an azure ad app, so what you need to do is set the scope and use msal to generate an access token, [this official sample](https://github.com/Azure-Samples/ms-identity-javascript-react-spa) shows how to generate a token for calling graph api, in your case, you need to change the scope(api://xxx/customScope) and api endpoint(localhost:4321/myapi) in authConfig. @StillANoob Pls forgive me if I misunderstood some place. – Tiny Wang Mar 23 '21 at 09:46
  • @Tiny-wa i already set the scope like that. with API endpoint do i need to replace it like this? export const graphConfig = { graphMeEndpoint: "https://localhost:44312/" }; – Mer Merced Mar 23 '21 at 10:46