How to validate token generated by Azure AD B2C?

Dilip Mevada 6 Reputation points
2021-03-03T08:52:29.617+00:00

Hi All, Here is my scenario, SignUp / SignIn by using Azure AD B2C Tenant, once we get the id token in the URL, and it will be stored in the Local Storage of the application. Now I want to use that id token to validate my custom API, if the token is valid based on clientId and ClientSecret then proceeds further in my custom API. I have tried many options but not working. Can someone share a sample code for it, that will be very help?

Azure Active Directory External Identities
0 comments No comments
{count} vote

6 answers

Sort by: Most helpful
  1. Andres Cardona 6 Reputation points
    2023-02-11T17:52:45.91+00:00

    Hi, the next code work for me, in my proyect .Net Core 6.0 Web App

    public bool CheckAzureTokenIsValid(string access_token, AzureConnectionDTO azureConnectionDTO)
            {
                string stsDiscoveryEndpoint = "https://xxx.b2clogin.com/xxx.onmicrosoft.com/<policy-name>/v2.0/.well-known/openid-configuration";
    
                var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever()); //1. need the 'new OpenIdConnect...'  
                OpenIdConnectConfiguration config = configManager.GetConfigurationAsync().Result;
    
                TokenValidationParameters validationParameters = new TokenValidationParameters
                {
                    ValidateAudience = true,
                    ValidateIssuer = true,
                    ValidateIssuerSigningKey = true,
                    ValidateLifetime = true,
                    RequireSignedTokens = true,
                    ClockSkew = TimeSpan.Zero,
    
                    ValidAudience = azureConnectionDTO.ClientId,
    
                    IssuerSigningKeys = config.SigningKeys,
                    ValidIssuer = config.Issuer
                };
    
                JwtSecurityTokenHandler tokendHandler = new JwtSecurityTokenHandler();
                SecurityToken jwt;
                var validatedToken = (SecurityToken)new JwtSecurityToken();
    
                try
                {
                    var result = tokendHandler.ValidateToken(access_token, validationParameters, out jwt);
                    var dataToValidate = jwt as JwtSecurityToken;
    
                    return true;
    
                }
                catch (Exception ex)
                {
                    string m = ex.Message;
                    Console.WriteLine("FormatException: " + m);
                    return false;
                }            
            }
    
    1 person found this answer helpful.

  2. AmanpreetSingh-MSFT 55,551 Reputation points
    2021-03-04T07:26:13.133+00:00

    Hi @Dilip Mevada · Thank you for reaching out.

    I would suggest you to use Access Token when calling your custom API as ID token doesn't include Scope/Roles claim which API can use to perform authorization. Below is an ASP.Net core code snippet, you can refer to, for this purpose.
    Ref: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/4-WebApp-your-API/4-2-B2C

    Code for the Web App
    In Startup.cs, below lines of code enables Microsoft identity platform endpoint. This endpoint is capable of signing-in users both with their Work and School Accounts.

    services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAdB2C")  
                        .EnableTokenAcquisitionToCallDownstreamApi(new string[] { Configuration["TodoList:TodoListScope"] })  
                        .AddInMemoryTokenCaches();  
    

    - AddMicrosoftIdentityWebAppAuthentication : This enables your application to use the Microsoft identity platform endpoint. This endpoint is capable of signing-in users both with their Work and School and Microsoft Personal accounts.

    • EnableTokenAcquisitionToCallDownstreamApi : Enables the web app to call the protected API ToDoList Api.
    • AddInMemoryTokenCaches: Adds an in memory token cache provider, which will cache the Access Tokens acquired for the Web API.

    Code for the Web API
    In Startup.cs, below lines of code protects the web API with Microsoft identity platform.

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

    Please "Accept the answer" if the information helped you. This will help us and others in the community as well.

    0 comments No comments

  3. Dilip Mevada 6 Reputation points
    2021-03-08T09:25:25.653+00:00

    @AmanpreetSingh-MSFT , Thanks for quick response.

    Can you please give provide detailed steps for this token validation or required lines of code, that will be very helpful?

    Code :
    try
    {
    string token = "token here";

                string stsDiscoveryEndpoint = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";  
    
                var configManager = new ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever()); //1. need the 'new OpenIdConnect...'  
    
                OpenIdConnectConfiguration config = configManager.GetConfigurationAsync().Result;  
                TokenValidationParameters validationParameters = new TokenValidationParameters  
                {  
                    //decode the JWT to see what these values should be  
                    ValidAudience = "5dc671b0-988f-4abd-a1eb-b2bdcd59XXXX",  // Replaced values by XXXX  
                    IssuerSigningKeys = config.SigningKeys, //2. .NET Core equivalent is "IssuerSigningKeys" and "SigningKeys"  
                    ValidateIssuer = false,  
                    ValidIssuer = "https://login.microsoftonline.com/common",  
                    ValidateAudience = true,  
                    ValidateIssuerSigningKey = false,  
                    RequireExpirationTime = false,  
                    ValidateLifetime = false,  
                };  
    
                JwtSecurityTokenHandler tokendHandler = new JwtSecurityTokenHandler();  
    
                SecurityToken jwt;  
    
                var result = tokendHandler.ValidateToken(token, validationParameters, out jwt);  
    
                var s = jwt as JwtSecurityToken;  
    
            }  
            catch (Exception ex)  
            {  
                throw;  
            }  
    

    Error Details:
    IDX10501: Signature validation failed. Unable to match key:
    kid: 'System.String'.
    Exceptions caught:
    'System.Text.StringBuilder'.
    token: 'System.IdentityModel.Tokens.Jwt.JwtSecurityToken'.

    Thanks a lot in advance. Please advice.


  4. MT 6 Reputation points
    2021-10-14T13:42:50.397+00:00

    Has anybody actually got this working though? I CANNOT validate this damn token I'm getting because of an apparent invalid signature, I've also posted here >> https://learn.microsoft.com/en-us/answers/questions/589591/azure-b2c-token-validation-in-api-returns-401-unau.html


  5. Nagendra 1 Reputation point
    2022-04-14T15:53:41.8+00:00

    Im looking for some details as well. We have an expired token and the api call goes through without validating expiry. How to fix this?

    0 comments No comments