Настройка аутентификации JWT с использованием Identity Server и получение токена доступа

Я работаю над проектом, основанным на микросервисной архитектуре и использующим сервер идентификации 5.

Я настроил аутентификацию JWT с помощью Identity Server 5 следующим образом:

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;
}

Я хочу получить токен доступа. Но мой API не работает.

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

Как я могу получить токен доступа?

🤔 А знаете ли вы, что...
C# активно развивается и обновляется, с появлением новых версий и функциональности.


51
2

Ответы:

Вы можете получить токен из URI токена Identity Server.

вот код:

public async Task<string> GetTokenAsync()
{
    var httpClient = _httpClientFactory.CreateClient();
    var res = await httpClient.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
    {
        Address = _options.IdentityUrl + "/connect/token",
        ClientId = _options.ClientId,
        ClientSecret = _options.ClientSecret
    });
    _accessToken = res.AccessToken;

    return _accessToken;
}

Решено

Определите клиента с помощью 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"
    },
},

Затем вы можете получить токен доступа следующим образом:

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;

Для получения дополнительной информации см.: Конечная точка токена