3
votes

I am confused about how Azure B2C works when SPA is talking to backend APIs. We have a VUE app that retrieves data from ASPNet core Web APIs. I connected the VUE with APP on Azure B2C and I can login and retrieve access token, but.

How does authentication/authorization between SPA and APIs work?

TIA

2

2 Answers

2
votes

Azure B2C uses OATH 2 / OpenID Connect as the main way to secure single page apps and API's. OATH 2 uses Json Web Tokens (stateless cryptographically signed tokens) to provide authentication between multiple services (OpenID Connect is an extension of OATH 2).

The Client application (the SPA in this case) would ask Azure AD B2C for JWT tokens. If the user is logged in to B2C the security token service would then issue tokens for the SPA to use.

When the SPA calls the API, the ID token from the security token service (in the OpenID Connect flow) would be sent to the API in the Authorization header (Authorization: Bearer $token$). The API could then validate the token based on the signature block of the JWT to validate that the token was issued by the security token service and has not been modified. Because of the trust relationship between the STS and the API (the API trusts the STS), the API then authenticates and authorizes the various api calls based on the JWT that is presented.

Since you have the SPA working and getting tokens, all you need to do next is set up the Web API to accept the JWT from B2C. Using Microsoft.AspNetCore.Authentication.JwtBearer the following code should be close to getting you up and running

services.AddAuthentication(options =>
  { 
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; 
  })
  .AddJwtBearer(jwtOptions =>
  {
    jwtOptions.Authority = $"https://login.microsoftonline.com/tfp/{Configuration["AzureAdB2C:Tenant"]}/{Configuration["AzureAdB2C:Policy"]}/v2.0/";
    jwtOptions.Audience = Configuration["AzureAdB2C:ClientId"];
    jwtOptions.Events = new JwtBearerEvents
    {
      OnAuthenticationFailed = AuthenticationFailed
    };
  });

(above code from azure samples, no longer maintained.

While Ideally both the SPA and API would be registered as separate clients with the STS, you could use the same client ID so you would not need to keep two sets of tokens around, one for the SPA client and one for the API. In the current project I am working on, multiple SPA's are registered as clients then the API has an AddJwtBearer which accepts multiple audiences

.AddJwtBearer(options =>
{
    options.Authority = $"https://login.microsoftonline.com/tfp/{Configuration["AzureAdB2C:Tenant"]}/{Configuration["AzureAdB2C:Policy"]}/v2.0/";
    options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidAudiences = new List<string> 
        {
            Configuration["AzureAdB2C:ClientId1"];,
            Configuration["AzureAdB2C:ClientId2"]; 
        }
    };
}

This gives enough security to me for my app and the API does not need to be registered as a client with the IDP.

-1
votes

I Hope you are aware of the web app/SPA registration process like

  1. Select App registrations, select the Owned applications tab, and then select the webapp1 application.
  2. Under Web, select the Add URI link, enter http://localhost:6420.
  3. Under Implicit Grant, select the checkboxes for Access Tokens and ID Tokens and then select Save.
  4. Record the Application (client) ID for use in a later step when you update the code in the single-page web application.

In the same manner we will create a web API

  1. Select App registrations, and then select New registration.
  2. Enter a Name for the application. For example, webapi1.
  3. Under Redirect URI, select Web, and then enter an endpoint where Azure AD B2C should return any tokens that your application requests. In this tutorial, the sample runs locally and listens at http://localhost:5000.
  4. Record the Application (client) ID for use in a later step.

Then we need to configure scopes. These Scopes provide a way to govern access to protected resources. Scopes are used by the web API to implement scope-based access control. Please go through the document on how to provide scope for web API.

And Need to Grant permission to the web API in the Web APP which we created at first. This permission helps the generated access token at Web APP to be validated/Autorized at the web API. Please go through the steps as mentioned in the document