Ich versuche, eine wirklich einfache Implementierung der JWT-Trägerauthentifizierung mit ASP.NET Core durchzuführen. Ich antworte ein bisschen wie folgt:
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())
);
Ich habe Jwt-Middleware für eingehende Anfragen:
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = tokenValidationParameters
});
Dies scheint zu funktionieren, um Ressourcen mit dem Berechtigungsattribut zu schützen, aber die Ansprüche werden nie angezeigt.
[Authorize]
public async Task<IActionResult> Get()
{
var user = ClaimsPrincipal.Current.Claims; // Nothing here
Sie können ClaimsPricipal.Current
nicht in einer ASP.NET Core-Anwendung verwenden, da sie nicht von der Laufzeitumgebung festgelegt wird. Für weitere Informationen lesen Sie https://github.com/aspnet/Security/issues/322 .
Verwenden Sie stattdessen die User
-Eigenschaft, die von ControllerBase
verfügbar gemacht wird.
Zugriff auf User.Claims
anstelle von ClaimsPrinciple.Current.Claims
.
Von der Einführung in die Identität bei docs.asp.net :
In der Aktionsmethode
HomeController.Index
können Sie dieUser.Claims
-Details anzeigen.
Hier ist der relevante Quellcode aus dem MVC-Repository:
public ClaimsPrincipal User
{
get
{
return HttpContext?.User;
}
}
Als Teil von ASP.NET Core 2.0 können Sie die oben beschriebenen JWT-Claims wie Shaun lesen. Wenn Sie nur nach der Benutzer-ID suchen (stellen Sie sicher, dass Sie diese bereits als Teil des Antrags mit dem Antragsnamen "Sub" hinzufügen), können Sie je nach Anwendungsfall die folgenden zwei Beispiele verwenden:
User ID-Anspruch lesen:
public class AccountController : Controller
{
[Authorize]
[HttpGet]
public async Task<IActionResult> MethodName()
{
var userId = _userManager.GetUserId(HttpContext.User);
//...
return Ok();
}
}
Lesen Sie weitere Ansprüche:
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();
}
}
Mit dieser Lösung können Sie auf User.Identiy
und seine Ansprüche in Controllern zugreifen, wenn Sie Jwt-Token verwenden:
schritt 1: Erstellen Sie eine 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();
}));
}
}
schritt 2: Verwenden Sie es in Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
app.UseJwtTokenMiddleware();
}