簡體   English   中英

無法使用 ASP.NET Core 從 JWT 令牌中獲取聲明

[英]Can't get claims from JWT token with ASP.NET Core

我正在嘗試使用 ASP.NET Core 做一個非常簡單的 JWT 承載身份驗證實現。 我從控制器返回一個響應,有點像這樣:

    var identity = new ClaimsIdentity();
    identity.AddClaim(new Claim(ClaimTypes.Name, applicationUser.UserName));
        var jwt = new JwtSecurityToken(
             _jwtOptions.Issuer,
             _jwtOptions.Audience,
             identity.Claims,
             _jwtOptions.NotBefore,
             _jwtOptions.Expiration,
             _jwtOptions.SigningCredentials);

       var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

       return new JObject(
           new JProperty("access_token", encodedJwt),
           new JProperty("token_type", "bearer"),
           new JProperty("expires_in", (int)_jwtOptions.ValidFor.TotalSeconds),
           new JProperty(".issued", DateTimeOffset.UtcNow.ToString())
       );

我有用於傳入請求的 Jwt 中間件:

app.UseJwtBearerAuthentication(new JwtBearerOptions
{
     AutomaticAuthenticate = true,
     AutomaticChallenge = true,
     TokenValidationParameters = tokenValidationParameters
});

這似乎可以保護具有授權屬性的資源,但聲明從未出現。

    [Authorize]
    public async Task<IActionResult> Get()
    {
        var user = ClaimsPrincipal.Current.Claims; // Nothing here

您不能在 ASP.NET Core 應用程序中使用ClaimsPricipal.Current ,因為它不是由運行時設置的。 您可以閱讀https://github.com/aspnet/Security/issues/322了解更多信息。

相反,請考慮使用由ControllerBase公開的User屬性。

訪問User.Claims而不是ClaimsPrinciple.Current.Claims

來自 docs.asp.net 的身份簡介

...在HomeController.Index操作方法中,您可以查看User.Claims詳細信息。

這是來自 MVC 存儲庫的相關源代碼

public ClaimsPrincipal User
{
   get
   {
       return HttpContext?.User;
   }
}

作為 ASP.NET Core 2.0 的一部分,您可以像上述 Shaun 一樣閱讀 JWT 聲明。 如果您只是在尋找用戶 ID(確保您已經使用“Sub”聲明名稱將其添加為聲明的一部分),那么您可以根據您的用例使用以下兩個示例來閱讀:

讀取用戶 ID 聲明:

    public class AccountController : Controller
    {
        [Authorize]
        [HttpGet]
        public async Task<IActionResult> MethodName()
        {
            var userId = _userManager.GetUserId(HttpContext.User);
            //...
            return Ok();
        }
    }

閱讀其他聲明:

    public class AccountController : Controller
    {
        [Authorize]
        [HttpGet]
        public async Task<IActionResult> MethodName()
        {
            var rolesClaim = HttpContext.User.Claims.Where( c => c.Type == ClaimsIdentity.DefaultRoleClaimType).FirstOrDefault();
            //...
            return Ok();
        }
    }

使用此解決方案,您可以在使用 JWT 令牌時訪問控制器中的User.Identity及其聲明:

第 1 步:創建一個 JwtTokenMiddleware:

public static class JwtTokenMiddleware
{
    public static IApplicationBuilder UseJwtTokenMiddleware(
      this IApplicationBuilder app,
      string schema = "Bearer")
    {
        return app.Use((async (ctx, next) =>
        {
            IIdentity identity = ctx.User.Identity;
            if ((identity != null ? (!identity.IsAuthenticated ? 1 : 0) : 1) != 0)
            {
                AuthenticateResult authenticateResult = await ctx.AuthenticateAsync(schema);
                if (authenticateResult.Succeeded && authenticateResult.Principal != null)
                    ctx.User = authenticateResult.Principal;
            }
            await next();
        }));
    }
}

第二步:在Startup.cs中使用:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();
    app.UseJwtTokenMiddleware();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM