Search code examples
c#asp.net-coreoauth-2.0jwtidentityserver4

Setting up JWT authentication using the Identity Server and get access token


I am working on a project which is based on micro-service architecture and use the identity server 5.

I set up JWT authentication using the Identity Server 5 as follows:

public static IServiceCollection AddDefaultAuthentication(this IHostApplicationBuilder builder)
{
    var services = builder.Services;
    var configuration = builder.Configuration;

    // {
    //   "Identity": {
    //     "Url": "http://identity",
    //     "Audience": "basket"
    //    }
    // }

    var identitySection = configuration.GetSection("Identity");

    if (!identitySection.Exists())
    {
        // No identity section, so no authentication
        return services;
    }

    // prevent from mapping "sub" claim to nameidentifier.
    JsonWebTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");

    services.AddAuthentication().AddJwtBearer(options =>
        {
            var identityUrl = identitySection.GetRequiredValue("Url");
            var audience = identitySection.GetRequiredValue("Audience");
            options.Authority = identityUrl;
            options.RequireHttpsMetadata = false;
            options.Audience = audience;

            options.TokenValidationParameters = new TokenValidationParameters
            {
                #if DEBUG
                // Needed if using Android Emulator Locally. See https://learn.microsoft.com/en-us/dotnet/maui/data-cloud/local-web-services?view=net-maui-8.0#android
                ValidIssuers = [identityUrl, "https://10.0.2.2:5243"],
                #else
                ValidIssuers = [identityUrl],
                #endif
                ValidateAudience = false,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Constants.SecurityKey)),
                ValidTypes = new[] { "at+jwt" },
            };
        });

    services.AddAuthorization();
        
    return services;
}

I want to get access token. But my API is not working.

api.MapGet("/token",  
           async (HttpContext context) => 
                 await context.GetTokenAsync("access_token"));

How can I get the access token?


Solution

  • Define a Client with GrantTypes.ResourceOwnerPassword

    new Client
    {
        ClientId = "webapp",
        ClientName = "WebApp Client",
        ClientSecrets = new List<Secret>
        {
            new Secret("secret".Sha256())
        },
        ClientUri = $"{configuration["WebAppClient"]}",                             
        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
        AllowedScopes = new List<string>
        {
            IdentityServerConstants.StandardScopes.OpenId,
            "bpms"
        },
    },
    

    Then, you can get access token as follows:

    var httpClient = service.HttpClientFactory.CreateClient();
    var res = await httpClient.RequestPasswordTokenAsync(new PasswordTokenRequest
    {
        Address = identityUrl + "/connect/token",
        ClientId = "webapp",
        ClientSecret = "secret",
        //Scope = "bpms",
        UserName ="alice",
         Password="Pass123$"
    });
    var accessToken = res.AccessToken;
    

    For more information see: Token Endpoint