Asp.net核心2.1基于角色的授权不适用于JWT

时间:2019-03-14 18:19:05

标签: c# asp.net asp.net-core

我当前遇到的问题是,具有有效声明身份的给定客户端指定该客户端处于给定角色,而未获得需要该角色的操作和控制器的授权。

我正在使用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"
}

0 个答案:

没有答案