当前位置:  开发笔记 > 编程语言 > 正文

UseJwtBearerAuthentication不会填充User.Identity.Name

如何解决《UseJwtBearerAuthentication不会填充User.Identity.Name》经验,为你挑选了2个好方法。

我试图JWTASP.NET Core Web API项目中使用身份验证机制.假设此项目没有MVC部分,并且不使用cookie身份验证.我已根据本指南创建了我的代码.

登录工作好,保护与[Authorize]属性工作正常,但User.Identity.Name就是null.我怎样才能解决这个问题?

我的代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
    var tokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],

        ValidateAudience = true,
        ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],

        ValidateIssuerSigningKey = true,
        IssuerSigningKey = _signingKey,

        RequireExpirationTime = true,
        ValidateLifetime = true,

        ClockSkew = TimeSpan.Zero
    };

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

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

    [HttpPost]
    [AllowAnonymous]
    [Route("Login")]
    public async Task Login([FromForm] ApplicationUser applicationUser)
    {
        //assume user/pass are checked and are ok

        _logger.LogInformation(1, "API User logged in.");
        var user = await _userManager.FindByNameAsync(applicationUser.UserName);
        var roles = await _userManager.GetRolesAsync(user);

        var claims = new List
        {
            new Claim(JwtRegisteredClaimNames.Sub, applicationUser.UserName),
            new Claim(ClaimTypes.NameIdentifier, applicationUser.UserName),
            new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()),
            new Claim(JwtRegisteredClaimNames.Iat,
                    ToUnixEpochDate(_jwtOptions.IssuedAt).ToString(),
                    ClaimValueTypes.Integer64),
                    new Claim("Claim", "Value")
        };

        if (roles != null)
            foreach (var role in roles)
                claims.Add(new Claim("role", role));

        // Create the JWT security token and encode it.
        var jwt = new JwtSecurityToken(
            issuer: _jwtOptions.Issuer,
            audience: _jwtOptions.Audience,
            claims: claims,
            notBefore: _jwtOptions.NotBefore,
            expires: _jwtOptions.Expiration,
            signingCredentials: _jwtOptions.SigningCredentials);

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

        // Serialize and return the response
        var response = new
        {
            access_token = encodedJwt,
            expires_in = (int)_jwtOptions.ValidFor.TotalSeconds
        };

        var json = JsonConvert.SerializeObject(response, _serializerSettings);
        return new OkObjectResult(json);
    }

jps.. 22

在您的声明(第二个代码段)中,我只能看到这个:

new Claim(ClaimTypes.NameIdentifier, applicationUser.UserName),

但你需要添加这个:

new Claim(ClaimTypes.Name, applicationUser.UserName),

那么User.Identity.Name应该包含用户名.



1> jps..:

在您的声明(第二个代码段)中,我只能看到这个:

new Claim(ClaimTypes.NameIdentifier, applicationUser.UserName),

但你需要添加这个:

new Claim(ClaimTypes.Name, applicationUser.UserName),

那么User.Identity.Name应该包含用户名.



2> Michael Earl..:

另一种选择是设置命名空间中JwtRegisteredClaimNames.SubtokenValidationParameters。这将使您继续使用该标准:

var tokenValidationParameters = new TokenValidationParameters
{
    // Ensure that User.Identity.Name is set correctly after login
    NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",

    ... existing code ...
}

更新:Diogo Barros在我的博客上就此主题发表了评论:

“你好,

谢谢您的帮助。这对我有用。为了获得更高的一致性和安全性,可以使用ClaimTypes.NameIdentifier(在System.Security.Claims命名空间中)代替硬编码的字符串。”

我已经更改了代码以使用内置的ClaimTypes枚举,因为它比使用命名空间字符串更优雅。

推荐阅读
喜生-Da
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有