Как добавить пользовательские требования для доступа к токену в IdentityServer4?

Я использую IdentityServer4.

Я хочу добавить другие пользовательские заявки для доступа к токену, но я не могу этого сделать. Я изменил Quickstart5 и добавил ASP.NET Identity Core и пользовательские заявки через ProfileService, как это было предложено Coemgen ниже.

Вы можете скачать мой код здесь: zip package. (Он основан на: Quickstart5 с ASP.NET Identity Core и добавленными претензиями через ProfileService).

Ошибка: GetProfileDataAsync не выполняется.

Ответ 1

Вы должны реализовать свой собственный профиль. Взгляните на это сообщение, которое я последовал, когда я реализовал то же самое: https://damienbod.com/2016/11/18/extending-identity-in-identityserver4-to-manage-users-in-asp-net-core/

Вот пример моей собственной реализации:

public class ProfileService : IProfileService
{
    protected UserManager<ApplicationUser> _userManager;

    public ProfileService(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        //>Processing
        var user = _userManager.GetUserAsync(context.Subject).Result;

        var claims = new List<Claim>
        {
            new Claim("FullName", user.FullName),
        };

        context.IssuedClaims.AddRange(claims);

        //>Return
        return Task.FromResult(0);
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        //>Processing
        var user = _userManager.GetUserAsync(context.Subject).Result;

        context.IsActive = (user != null) && user.IsActive;

        //>Return
        return Task.FromResult(0);
    }

}

Не забудьте добавить эту строку в свой Startup.cs

services.AddTransient<IProfileService, ProfileService>();

Ответ 2

Хорошо, здесь проблема:

хотя вы правильно настроили доступные ресурсы Identity (как стандартные, так и пользовательские), вам также необходимо явно определить, какие из них необходимы при вызове вашего ресурса api. Для того, чтобы определить это, вы должны пойти в Config.cs класс по ExampleIdentityServer проекта и предоставить третий аргумент, как на new ApiResouirce конструктора. Только те, которые будут включены в access_token

// scopes define the API resources in your system
public static IEnumerable<ApiResource> GetApiResources()
{
    return new List<ApiResource>
    {
        new ApiResource("api1", "My API", new[] { JwtClaimTypes.Subject, JwtClaimTypes.Email, JwtClaimTypes.Phone, etc... })
    };
}

По сути, это означает, что я получил свои требования к идентификации, настроенные для моей организации, но может быть задействовано более одного API-интерфейса, и не все API-интерфейсы используют все доступные утверждения профиля. Это также означает, что они будут присутствовать внутри вашего ClaimsPrincipal Все остальные могут быть доступны через конечную точку "userinfo" в качестве обычного HTTP-вызова.

ПРИМЕЧАНИЕ. Что касается токенов обновления:

Если вы решили включить токены обновления через AllowOfflineAccess = true, вы можете столкнуться с таким же поведением при обновлении access_token " GetProfileDataAsync не выполняется! ". Таким образом, претензии внутри access_token остаются неизменными, хотя вы получаете новый access_token с обновленным временем жизни. Если это так, вы можете заставить их всегда обновляться из службы профиля, устанавливая UpdateAccessTokenClaimsOnRefresh=true в конфигурации клиента.

Ответ 3

Обнаружена проблема.

В startup.cs вместо добавления "services.AddTransient();"

Добавить ".AddProfileService()" в services.AddIdentityServer()

Вы закончите с

        services.AddIdentityServer()
            .AddTemporarySigningCredential()
            .AddInMemoryIdentityResources(Config.GetIdentityResources())
            .AddInMemoryApiResources(Config.GetApiResources())
            .AddInMemoryClients(Config.GetClients())
            .AddAspNetIdentity<ApplicationUser>()
            .AddProfileService<ProfileService>();

Спасибо, что помогли Коемгэну! ничего плохого в коде, просто запуск был неправильным.

Ответ 4

Вы можете включить любые претензии с помощью параметра UserClaims в свой GetIdentityResources() в классе конфигурации:

UserClaims: список связанных типов заявок пользователей, которые должны быть включены в токен идентификации. (Согласно официальной документации) http://docs.identityserver.io/en/release/reference/identity_resource.html#refidentityresource