我目前正在将我的Web API 2.0转换为.NET Core Web API,但是我正在努力解决其中一部分。
在我现有的API中,我有一个带有以下代码的属性:
public class JwtAuthentication : Attribute, IAuthenticationFilter
{
public string Realm { get; set; }
public bool AllowMultiple => false;
public async Task AuthenticateAsync(
HttpAuthenticationContext context,
CancellationToken cancellationToken)
{
var request = context.Request;
var authorization = request.Headers.Authorization;
// checking request header value having required scheme "Bearer" or not.
if (authorization == null ||
authorization.Scheme.ToLowerInvariant() != "bearer" ||
string.IsNullOrEmpty(authorization.Parameter))
{
context.ErrorResult = new AuthenticationFailureResult("JWT Token is Missing", request);
return;
}
// Getting Token value from header values.
var token = authorization.Parameter;
var principal = await AuthJwtToken(token);
if (principal == null)
{
context.ErrorResult = new AuthenticationFailureResult("Invalid JWT Token", request);
}
else
{
context.Principal = principal;
}
}
private static bool ValidateToken(string token, out ICollection<Claim> claims)
{
claims = null;
var simplePrinciple = JwtAuthManager.GetPrincipal(token);
if (simplePrinciple == null)
{
return false;
}
var identity = simplePrinciple.Identity as ClaimsIdentity;
if (identity == null)
{
return false;
}
if (!identity.IsAuthenticated)
{
return false;
}
var usernameClaim = identity.FindFirst(ClaimTypes.Name);
var emailClaim = identity.FindFirst(ClaimTypes.Email);
var username = usernameClaim?.Value;
var email = emailClaim?.Value;
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(email))
{
return false;
}
claims = identity.Claims.ToList();
return true;
}
protected Task<IPrincipal> AuthJwtToken(string token)
{
if (ValidateToken(token, out var claims))
{
var identity = new ClaimsIdentity(claims, "Jwt");
IPrincipal user = new ClaimsPrincipal(identity);
return Task.FromResult(user);
}
return Task.FromResult<IPrincipal>(null);
}
public Task ChallengeAsync(
HttpAuthenticationChallengeContext context,
CancellationToken cancellationToken)
{
Challenge(context);
return Task.FromResult(0);
}
private void Challenge(HttpAuthenticationChallengeContext context)
{
string parameter = null;
if (!string.IsNullOrEmpty(Realm))
{
parameter = "realm=\"" + Realm + "\"";
}
context.ChallengeWith("Bearer", parameter);
}
}
如果我正确理解,在ASP.NET Core中,我要做的就是在启动时定义以下内容:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});
而且我不确定是否需要以下内容,但看起来像这样:
services.AddMvc();
而且我所能做的就是使用[Authorize]属性,但是如果我想复制在ASP.NET MVC Web API 2.0中使用的属性怎么办?
我应该吗?我喜欢这样的事实,我可以看到令牌出现问题的地方。如果可以相同的方式使用它并假设可以这样做,我该怎么做?谷歌搜索解决方案时,我还没有找到任何有用的方法?
谢谢。
我想您不想重新发明整个承载令牌认证轮。
如果要自定义事件的处理方式,可以使用JwtBearerOptions.Events Property将您自己的委托挂接到一个或多个事件上。 ([OnAuthenticationFailed Property,OnChallenge Property,OnMessageReceived Property,OnTokenValidated Property)。
示例失败的身份验证日志记录。
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
options.Events.OnAuthenticationFailed = (context) =>
{
// Log failed authentication here
// Return control back to JWT Bearer middleware
return Task.CompletedTask;
}
});
希望有帮助