Asp.net core 2.1 Ролевая авторизация не работает с JWT - PullRequest
0 голосов
/ 14 марта 2019

В настоящее время у меня возникают проблемы, при которых указанный клиент, имеющий действительное удостоверение претензии, указывающее, что клиент находится в данной роли, не авторизован для действий и контроллеров, которым требуется эта роль.

I 'Используя API для генерации токена, который клиент будет использовать для доступа как к API, так и к веб-сайту, токены генерируются как JWT.

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

Я использую HttpContext.Signin для входа в систему пользователя, передавая ему токен, полученный от API, который содержит роли пользователяи другие претензии.

Я включил код, который имеет дело с токенами, и токен, полученный от API - в самом конце -.Как ясно видно, у пользователя есть атрибут роли, но он не будет авторизован промежуточным ПО для аутентификации.

Создание токена

    public async Task<string> CreateBearerTokenAsync(User user, string audience)
    {
        // Create identity for the client
        var claims = await _clientManager.CreateUserClaimsIdentityAsync(user.Id);

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = claims,
            Expires = DateTime.UtcNow.AddHours(2),
            IssuedAt = DateTime.UtcNow,
            Issuer = "Bikefy Api",
            Audience = audience,
            SigningCredentials = _encryptionService.TokenSignKey
        };

        // Create the token
        var token = new JwtSecurityTokenHandler().CreateJwtSecurityToken(tokenDescriptor);

        // Write the token to string.
        return new JwtSecurityTokenHandler().WriteToken(token);
    }

Идентификация утверждений

    public async Task<ClaimsIdentity> CreateUserClaimsIdentityAsync(Guid clientId)
    {
        if (clientId == null || Guid.Empty == clientId)
            throw new ArgumentNullException($"{nameof(clientId)}");

        var user = await GetClientByIdAsync(clientId);
        var id = new ClaimsIdentity("ApiKey", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
        var secKey = await GetSecurityStampAsync(clientId);

        // Add default claims
        id.AddClaim(new Claim(ClaimTypes.NameIdentifier, clientId.ToString(), ClaimValueTypes.String));
        if (user.FirstName != null)
            id.AddClaim(new Claim(ClaimTypes.GivenName, user.FirstName, ClaimValueTypes.String));
        if (user.LastName != null)
            id.AddClaim(new Claim(ClaimTypes.Surname, user.LastName, ClaimValueTypes.String));

        id.AddClaim(new Claim(IdentityProviderClaimType, "Bikey Identity", ClaimValueTypes.String));
        id.AddClaim(new Claim(SecurityStampClaimType, secKey, ClaimValueTypes.String));
        if (user.RoleName != null)
            id.AddClaim(new Claim($"{nameof(User.RoleName)}", user.RoleName, ClaimValueTypes.String));

        // Get roles 
        var roles = await GetRolesAsync(clientId);
        foreach (var role in roles)
            id.AddClaim(new Claim(ClaimTypes.Role, role));

        // Add user claims
        id.AddClaims(await GetClaimsAsync(clientId));

        return id;
    }

Конфигурация токена cookie

    public static void ConfigureAuthentication(this IServiceCollection services, IConfiguration configuration)
    {
        var secretKeys = new SecretKeys();
        configuration.GetSection("SecretKeys").Bind(secretKeys);

        var encryptService = new EncryptionService("00E7EB8C24190E2187", secretKeys);
        services.AddSingleton(encryptService);
        services.AddSingleton(secretKeys);

        services.AddAuthentication(x =>
        {
            x.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;

            x.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

        }).AddCookie(c =>
        {
            c.Cookie.Name = "CityCyles.Auth";
            c.Cookie.HttpOnly = true;
            c.Cookie.Expiration = TimeSpan.FromDays(1);
            c.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always;
            c.LoginPath = $"/Account/Login";
            c.LogoutPath = $"/Account/Logout";
            c.AccessDeniedPath = $"/Account/AccessDenied";
        });

    }

Логин пользователя

        try
        {
            result = await _apiProvider.SendPostRequest(_apiProvider.BuildUrl("Auth", "Authenticate"), apiModel);

            // Convert the string into a token
            var token = new JwtSecurityTokenHandler().ReadJwtToken(result);

            // Create cookie options
            var authOptions = new AuthenticationProperties()
            {
                AllowRefresh = model.Remember,
                ExpiresUtc = DateTime.UtcNow.AddHours(2),
                IssuedUtc = DateTime.UtcNow,
                IsPersistent = true
            };

            // Get the user claims from the user
            var claimsIdentity = new ClaimsIdentity(token.Claims, CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);

            // Sign in the user
            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authOptions);

            // Redirect the user to the requested page or take them home
            if (!string.IsNullOrEmpty(returnUrl))
                return Redirect(returnUrl);

            return RedirectToAction("Index", "Home");

        }
        catch (WebException ex)
        {
            _logger.LogWarning(LogEvents.HandlingLogin, ex, "Error  authenticating user.");

            //Display the error
            ModelState.AddModelError("Custom-Error", ex.Message);

            return View(model);
        }

Действие контроллера

    [HttpGet]
    [Authorize(Roles = CityCyclesRoles.CityCyclesDocks)]
    public async Task<IActionResult> OnBoard()
    {
        return View();
    }

Токен

{
      "nameid": "3e637f01-85a9-4437-a113-50d2953d014e",
      "given_name": "Stephanie",
      "family_name": "Lee",
      "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider": "Bikey Identity",
      "Bikeyfy.Identity.SecurityStamp": "1b6228cf-945a-4503-a64e-1dcb7b649c22",
      "role": "CityCycles.Staff.Docks",
      "nbf": 1552586386,
      "exp": 1552593586,
      "iat": 1552586386,
      "iss": "CityCycles Api",
      "aud": "CityCycles.Web"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...