mohandes
mohandes

Reputation: 137

How to authenticate an access token which is obtained from azure ad b2c through an spa (react app), in a api (asp.net api)?

I have a react app as my client app and an asp.net api as my api (resources). I have managed to integrate azure ad b2c login in my client app. Now I am traying to send a request that contains the access token, to my api(which is now secured with azure ad b2c) to have access to my api resources. But I get status code 401 from the api that means unauthorized. I send the access token (bearer token) from client app (react) to the api like this:

         const tokenItem = sessionStorage.getItem('item1');

         const tokenjson = JSON.parse(tokenItem);
         const accessToken = tokenjson.secret;
         

         const tokenConfig = {
             headers: { Authorization: `Bearer ${accessToken}` }
         };
         axios.post('https://localhost:44304/func', model, tokenConfig)
                .then(response => {                                       
                    this.setState({ Result: response.data });
                })
                .catch(error => {
                    console.log(error)
                })

and in the api app, I have the code below in the Startup.cs

public void ConfigureServices(IServiceCollection services)
        {

            ...

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApi(options =>
            {
                Configuration.Bind("AzureAdB2C", options);

                options.TokenValidationParameters.NameClaimType = "name";
            },
            options => { Configuration.Bind("AzureAdB2C", options); });

            ...

}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
            ...
            app.UseAuthentication();

            app.UseAuthorization();
            ...

            
}

my appsettings.json in the api app is like this:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },


  "AzureAdB2C": {
    "Instance": "https://mytenantName.b2clogin.com",
    "Domain": "mytenantName.onmicrosoft.com",
    "ClientId": "my api client id ",
    "SignUpSignInPolicyId": "B2C_1_mySignupSignin_userflow"
  },
 
  "AllowedHosts": "*"
  
}

my controller is like below:

    [Authorize]
    [Route("[Controller]")]
    [RequiredScope("user.read", "user.write")]
    [ApiController]
    
    public class TokenController : Controller
    {     
        [HttpPost]
        public async Task<IActionResult> Func([FromBody] CreateModel model)
        {
            some functions...   
        }

    }

I should say that I can see access token in the client app (react). Why do I get status code 401 after sending the request to the api? Do I have something wrong in my code? I really appreciate any help :)

Upvotes: 2

Views: 1608

Answers (1)

kavya Saraboju
kavya Saraboju

Reputation: 10831

Looks like you are trying to access Microsoft Graph API instead of your backend api. (As your scope is :"User.Read" which is nothing but the scope for microsoft graph api ).

Your front-end app needs to use a scope for your API, not User.Read. This way it will get an access token which is meant for your API. Register a scope for your API app registration through the Expose an API section and use the scope in your front-end app.

enter image description here


enter image description here


How it looks

enter image description here

Note :Remove user.read permission which is for microsoft graph api.

Upvotes: 2

Related Questions