Добавление пользовательских требований (для авторизации) в Принципал на стороне Клиента - PullRequest
0 голосов
/ 03 марта 2020

Мне удалось успешно реализовать свой собственный сервер аутентификации IdentityServer4 на net ядре 3.1, и к нему подключилось клиентское веб-приложение. Клиент успешно получает токен доступа и идентификатор. Токен содержит всю информацию, идентифицирующую пользователя.

Моя следующая задача - добавить привилегии, которые пользователь имеет в клиенте, к HttpContext.User в качестве утверждений сразу после получения токена до того, как любая другая страница будет отображена. Привилегии хранятся в базе данных, связанной с пользователем посредством subjectId.

Мне нужна помощь, чтобы узнать, где можно добавить эти утверждения, чтобы моя политика авторизации могла работать с утверждениями в основном. Я хотел бы, чтобы процесс выполнялся каждый раз, когда выдан токен.

PS Я использую поток кода для сервера идентификации с GetClaimsFromUserInfoEndpoint = true и SaveTokens = true.

Спасибо!

Ответы [ 2 ]

1 голос
/ 04 марта 2020

Вы можете использовать Profile sevise в identityServer4:

 services .AddIdentityServer(x =>
            {
                x.IssuerUri = "null";
                x.Authentication.CookieLifetime = TimeSpan.FromDays(10);
            })
.
.
.          
              .AddProfileService<ProfileService>();

Это хорошая ссылка: http://docs.identityserver.io/en/latest/reference/profileservice.html И ProfileService Может быть похож на этот шаблон кода:

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


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

    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var subject = context.Subject ?? throw new ArgumentNullException(nameof(context.Subject));

        var subjectId = subject.Claims.Where(x => x.Type == "sub").FirstOrDefault().Value;

        var user = await _userManager.FindByIdAsync(subjectId);
        if (user == null)
            throw new ArgumentException("Invalid subject identifier");

        var claims = GetClaimsFromUser(user,subject);
        context.IssuedClaims = claims.Result.ToList();
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        var subject = context.Subject ?? throw new ArgumentNullException(nameof(context.Subject));

        var subjectId = subject.Claims.Where(x => x.Type == "sub").FirstOrDefault().Value;
        var user = await _userManager.FindByIdAsync(subjectId);

        context.IsActive = false;

        if (user != null)
        {
            if (_userManager.SupportsUserSecurityStamp)
            {
                var security_stamp = subject.Claims.Where(c => c.Type == "security_stamp").Select(c => c.Value).SingleOrDefault();
                if (security_stamp != null)
                {
                    var db_security_stamp = await _userManager.GetSecurityStampAsync(user);
                    if (db_security_stamp != security_stamp)
                        return;
                }
            }

            context.IsActive =
                !user.LockoutEnabled ||
                !user.LockoutEnd.HasValue ||
                user.LockoutEnd <= DateTime.Now;
        }
    }

    private async Task<IEnumerable<Claim>> GetClaimsFromUser(ApplicationUser user,ClaimsPrincipal subject)
    {
        var claims = new List<Claim>
        {
            new Claim(JwtClaimTypes.Subject, user.Id),
            new Claim(JwtClaimTypes.PreferredUserName, user.UserName),
            new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName)

        };

        if (!string.IsNullOrWhiteSpace(user.Name))
            claims.Add(new Claim("name", user.Name));

        if (!string.IsNullOrWhiteSpace(user.LastName))
            claims.Add(new Claim("last_name", user.LastName));


        return claims;
    }
}
0 голосов
/ 04 марта 2020

Вы можете сделать это с помощью события TokenValidated

    public class CustomJwtBearerEvents : JwtBearerEvents
{
    public override async Task TokenValidated(TokenValidatedContext context)
    {
        var claims = context.Principal.Claims.ToList();
        claims.Add(new Claim("key", "value"));
        context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, "Bearer"));        }
}

Затем зарегистрировать его при запуске

        services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
            {
              ...
                options.Events = new JwtBearerEvents();
                options.EventsType = typeof(CustomJwtBearerEvents);
            });
...