2017-01-24 27 views
6

almaz ASP.NET Core Web API projesinde kimlik doğrulama mekanizması için JWT kullanmayı deniyorum. Bu projenin MVC bölümünün olmadığını ve çerez kimlik doğrulamasını kullanmadığını varsayalım. Kodumu this guide'a dayanarak oluşturdum.UseJwtBearerAuthentication, User.Identity.Name

Giriş iyi çalışıyor ve özniteliği ile koruma çalışıyor ancak User.Identity.Namenull'dur. Bunu nasıl düzeltebilirim?

Kodum: En istemlerde

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<IActionResult> 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<Claim> 
     { 
      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); 
    } 

cevap

8

(ikinci kod parçacığı) Ben sadece bunu görebilirsiniz:

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

ancak bu eklemeniz gerekir:

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

daha sonra User.Identity.Name kullanıcı adını içermelidir.

+0

Şimdi bu çözüldü çok basit görünüyor! teşekkür ederim –

+0

kabul edilir, çözüldüğünü duyduğuma sevindim. – jps

+0

Seni seviyorum, @jps. Benim günümüzü yaptın, lol –

2

tokenValidationParameters'da JwtRegisteredClaimNames.Sub için ad alanını ayarlamak başka bir seçenektir. Bu standart kullanmaya devam sağlayacak:

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 ... 
} 

Güncelleme: Diogo Barros bu konuyla ilgili blogumda için yorum yaptı.

"Merhaba,

Yardımlarınız için teşekkürler Bu çalıştı Benim için Daha fazla tutarlılık ve güvenlik için, kodlanmış dizge yerine ClaimTypes.NameIdentifier (System.Security.Claims ad alanında) kullanabilirsiniz. "

Bunu test etmedim, ancak ad alanı dizesini kullanmaktan biraz daha zarif görünüyor.

+0

Jetonun "alt" alanını kullanmak kabul edilen cevaptan daha standart görünüyor ve aynı zamanda belirteç boyutunu biraz azaltıyor :-) – youen

İlgili konular