Как создать и использовать аутентификацию на основе ролей JWT?

Я перехожу по ссылке ниже.

https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login < / а>

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

И я пробовал использовать его как [Authorize(Policy = "admin")] или [Authorize(Policy = "ApiUser")] в контроллере, но каждый раз, когда я пытаюсь, я получаю unauthenticated использование postman. Что мне не хватает? как сделать аутентификацию на основе ролей на основе учебника?

Запуск

services.AddAuthorization(options =>
{
    options.AddPolicy("ApiUser", policy => policy.RequireClaim(Constants.Strings.JwtClaimIdentifiers.Rol, Constants.Strings.JwtClaims.ApiAccess));
});
services.AddAuthorization(options =>
    options.AddPolicy("admin", policy => policy.RequireRole("admin"))
);


Контроллер аутентификации

// POST api/auth/login
[HttpPost("login")]
public async Task<IActionResult> Post([FromBody]CredentialsViewModel credentials)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var identity = await GetClaimsIdentity(credentials.UserName, credentials.Password);



    if (identity == null)
    {
        //return null;
        return BadRequest(Error.AddErrorToModelState("login_failure", "Invalid username or password.", ModelState));
    }
    var id = identity.Claims.Single(c => c.Type == "id").Value; 
    var user = await _userManager.FindByIdAsync(id);
    IList<string> role = await _userManager.GetRolesAsync(user);
    var jwt = await Tokens.GenerateJwt(identity, role[0], _jwtFactory, credentials.UserName, _jwtOptions, new JsonSerializerSettings { Formatting = Formatting.Indented });


    return new OkObjectResult(jwt);

}

Я пробовал использовать все методы, но ни один из них не работал

[Authorize(Policy = "ApiUser")]
[HttpGet("getPolicy")]
public string GetPolicy()
{
    return "policyWorking";
}
[Authorize(Roles = "admin")]
[HttpGet("getAdmin")]
public string GetAdmin()
{
    return "adminWorking";
}
[Authorize ]
[HttpGet("getAuthorize")]
public string GetAuthorize()
{
    return "normal authorize Working";
}


person sesamii seed    schedule 23.04.2020    source источник


Ответы (2)


Во-первых, убедитесь, что вы добавили строку json в свой appsettings.json, иначе вы всегда получите 401 unauthorized:

"JwtIssuerOptions": {
    "Issuer": "webApi",
    "Audience": "http://localhost:5000/"
}

Что мне не хватает? как сделать аутентификацию на основе ролей на основе учебника?

1.Если вы хотите использовать следующий способ регистрации услуги:

services.AddAuthorization(options =>
    options.AddPolicy("admin", policy => policy.RequireRole("admin"))
);

Атрибут авторизации должен быть таким, как показано ниже:

[Authorize(Policy  = "admin")]

2.Если вы хотите использовать следующий способ:

[Authorize(Roles = "admin")]

Вам необходимо удалить сервис из Startup.cs:

//services.AddAuthorization(options =>
//    options.AddPolicy("admin", policy => policy.RequireRole("admin"))
//);

Затем не забудьте добавить заявку с ролью в JwtFactory.GenerateEncodedToken, как показано ниже:

public async Task<string> GenerateEncodedToken(string userName, ClaimsIdentity identity)
{
    var claims = new[]
    {
            new Claim(JwtRegisteredClaimNames.Sub, userName),
            new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()),
            new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(_jwtOptions.IssuedAt).ToString(), ClaimValueTypes.Integer64),
            identity.FindFirst(Helpers.Constants.Strings.JwtClaimIdentifiers.Rol),
            identity.FindFirst(Helpers.Constants.Strings.JwtClaimIdentifiers.Id),
            new Claim(ClaimTypes.Role,"admin")
    };
        //...
}
person Rena    schedule 24.04.2020
comment
Здесь весь мой проект. - person Rena; 24.04.2020
comment
Что здесь ааа? О Боже!!! appsetting.json !! это была проблема! - person sesamii seed; 24.04.2020
comment
Когда я пойду по этому пути //services.AddAuthorization(options = ›// options.AddPolicy (admin, policy =› policy.RequireRole (admin)) //); как я могу установить роли и использовать это? в твоем гитхабе есть примеры? В любом случае, большое спасибо - person sesamii seed; 24.04.2020
comment
Это администратор, я его изменил. Если мой ответ вам помог, не могли бы вы принять как ответ - person Rena; 24.04.2020
comment
Могу я спросить последнее? Как отличить администратора от apiUser? Как это сделано? При входе в систему теперь автоматически используется apiuser, тогда как я могу создать другие политики и использовать их? у вас есть пример или статьи? - person sesamii seed; 24.04.2020
comment
У меня есть таблицы идентификации, и я хочу использовать aspnetRole, а если я воспользуюсь вторым способом, я могу использовать эту таблицу, как вы думаете? - person sesamii seed; 24.04.2020
comment
Я думаю, вы могли бы добавить оператор if для оценки роли пользователя в методе GenerateEncodedToken. Вы можете получить информацию о пользователе по имени пользователя и получить роль, например, здесь. Тогда сгенерированный токен будет другим. - person Rena; 24.04.2020

Я сделал свой, используя это руководство.

Он также работает с .Net Core 3.1.

@Обновлять

Для этого я использую политики:

services.AddAuthorization(options => {
    options.AddPolicy(Policies.RequireAny, policy =>
        policy.RequireClaim(JwtClaimTypes.Role, Enum.GetNames(typeof(AvailableRoles))));
    options.AddPolicy(Policies.RequireAdmin, policy =>
        policy.RequireClaim(JwtClaimTypes.Role,
            AvailableRoles.Admin.ToString()));
});

И в контроллере

[HttpDelete("{id:int:min(1)}")]
[Authorize(Policy = Policies.RequireAdmin)]
public async Task<IActionResult> Delete(int id) {
    // CODE
    return Ok();
}

и при создании токена JWT:


// Other claims and code...

claims.Add(new Claim(JwtClaimTypes.Role, roles[0]))
var token = new JwtSecurityToken(
    issuer:_appSettings.AppUrl,
    audience:_appSettings.AppUrl,
    claims: claims,
    expires: expires,
    signingCredentials: credentials
);

return new JwtSecurityTokenHandler().WriteToken(token);
person Morasiu    schedule 23.04.2020
comment
допустим, вы можете получать данные с помощью токена, тогда как вы используете роль? ограничить доступ? не могли бы вы рассказать, как вы это сделали? - person sesamii seed; 24.04.2020
comment
Слежу точно, не работает 401 несанкционированный - person sesamii seed; 24.04.2020
comment
Добавлены дополнительные пояснения - person Morasiu; 24.04.2020