web-dev-qa-db-ja.com

ASP.NET CoreでJWTトークンからクレームを取得できません

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属性を使用してリソースを保護するように機能するようですが、クレームは表示されません。

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

ASP.NET Coreアプリケーションでは、ClaimsPricipal.Currentを使用できません。ランタイムによって設定されないためです。詳細については、 https://github.com/aspnet/Security/issues/322 を参照してください。

代わりに、Userによって公開されるControllerBaseプロパティの使用を検討してください。

17
Pinpoint

アクセスUser.Claims の代わりに ClaimsPrinciple.Current.Claims

docs.asp.netのIdentityの概要から

...HomeController.Indexアクションメソッド、User.Claims詳細。

関連するソースコードはこちら MVCリポジトリから:

public ClaimsPrincipal User
{
   get
   {
       return HttpContext?.User;
   }
}
9
Shaun Luttin

ASP.NET Core 2.0の一部として、上記のShaunのようなJWTクレームを読むことができます。ユーザーIDのみを探している場合(「Sub」クレーム名を使用してクレームの一部として既に追加していることを確認してください)、次の2つの例を使用してユースケースに応じて読むことができます。

ユーザー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();
        }
    }
3
Tony

このソリューションにより、User.IdentiyおよびJwtトークンを使用している場合のコントローラーでのそのクレーム:

ステップ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();
        }));
    }
}

ステップ2:Startup.csで使用:

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