Добавление заявок в настройку IdentityServer с помощью AddIdentityServer - PullRequest
1 голос
/ 23 мая 2019

У меня есть SPA, у которого есть веб-API ASP.NET Core вместе со встроенным сервером идентификации, включенным с помощью AddIdentityServer, а затем AddIdentityServerJwt:

services.AddIdentityServer()
   .AddApiAuthorization<User, UserDataContext>();
services.AddAuthentication()
   .AddIdentityServerJwt();

У меня также есть настройка политики авторизациидля этого требуется утверждение роли «Администратор»:

services.AddAuthorization(options =>
{
    options.AddPolicy("IsAdmin", policy => policy.RequireClaim(ClaimTypes.Role, "Admin")); 
});

У меня есть действие контроллера, использующее эту политику

[Authorize(Policy = "IsAdmin")]
[HttpDelete("{id}")]
public IActionResult Deleten(int id)
{
    ...
}

Аутентифицированный пользователь имеет утверждение роли «Администратор»:

enter image description here

Маркер доступа для этого пользователя аутентификации не содержит утверждения администратора:

enter image description here

Я получаю 403 обратно при попытке запросить этот ресурс у администратора:

enter image description here

Итак, если яПри правильном понимании IdentityServer не включает утверждение о роли администратора, и поэтому пользователь не авторизован для доступа к ресурсу.

Можно ли настроить утверждения, которые IdentityServer использует, используя AddIdentityServerJwt?или я неправильно понимаю, почему это не работает.

Ответы [ 2 ]

1 голос
/ 24 мая 2019

На стороне Identity Server вы можете создать Службу профилей , чтобы IDS4 включал role утверждение при выдаче токенов.

Вы можете получить утверждения о роли из ClaimsPrincipal или получить роли из базы данных.и создайте службу профилей, например:

public class MyProfileService : IProfileService
{
    public MyProfileService()
    { }

    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        //get role claims from ClaimsPrincipal 
        var roleClaims = context.Subject.FindAll(JwtClaimTypes.Role);

        //add your role claims 
        context.IssuedClaims.AddRange(roleClaims);
        return Task.CompletedTask;
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        // await base.IsActiveAsync(context);
        return Task.CompletedTask;
    }
}

И зарегистрируйтесь в Startup.cs:

services.AddTransient<IProfileService, MyProfileService>();

На стороне клиента вы должны сопоставить заявку на роль из вашего токена JWT и попробовать следующую конфигурацию вAddOpenIdConnect middleware:

  options.ClaimActions.MapJsonKey("role", "role", "role");
  options.TokenValidationParameters.RoleClaimType = "role";

Тогда ваш API может проверить токен доступа и авторизоваться с помощью политики ролей.

0 голосов
/ 27 мая 2019

Я сделал это без использования ролей, но с использованием специальной заявки, добавленной в маркер пользователя. Я создал CustomUserClaimsPrincipalFactory, который позволяет мне добавлять дополнительные претензии к пользователю.

регистр

services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, CustomUserClaimsPrincipalFactory>();

код.

public class CustomUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole<long>>
    {
        public CustomUserClaimsPrincipalFactory(
            UserManager<ApplicationUser> userManager,
            RoleManager<IdentityRole<long>> roleManager,
            IOptions<IdentityOptions> optionsAccessor)
            : base(userManager, roleManager, optionsAccessor)
        {
        }

        protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
        {  
            var userId = await UserManager.GetUserIdAsync(user);
            var userName = await UserManager.GetUserNameAsync(user);
            var id = new ClaimsIdentity("Identity.Application", 
                Options.ClaimsIdentity.UserNameClaimType,
                Options.ClaimsIdentity.RoleClaimType);
            id.AddClaim(new Claim(Options.ClaimsIdentity.UserIdClaimType, userId));
            id.AddClaim(new Claim(Options.ClaimsIdentity.UserNameClaimType, user.Name));
            id.AddClaim(new Claim("preferred_username", userName));
            id.AddClaim(new Claim("culture", user.Culture ?? "da-DK"));
            if (UserManager.SupportsUserSecurityStamp)
            {
                id.AddClaim(new Claim(Options.ClaimsIdentity.SecurityStampClaimType,
                    await UserManager.GetSecurityStampAsync(user)));
            }
            if (UserManager.SupportsUserClaim)
            {
                id.AddClaims(await UserManager.GetClaimsAsync(user));
            }

            if(user.IsXenaSupporter)
               id.AddClaim(new Claim("supporter", user.Id.ToString()));
            return id;
        }
    }

политика

services.AddAuthorization(options =>
            {
                options.AddPolicy("Supporter", policy => policy.RequireClaim("supporter"));
            });

использование

    [Authorize(AuthenticationSchemes = "Bearer", Policy = "Supporter")]
    [HttpPost("supporter")]
    public async Task<ActionResult> ChangeToSpecificUser([FromBody] ChangeUserRequest request)
    {

     // .................. 

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...