[英]ASP.NET core 3 Customized authentication with jwt
I am using jwt tokens in my project.我在我的项目中使用 jwt 令牌。 When the client logins, he will receive a token with his device id (in mobile) -that was sent to the server in the request body- as the payload...当客户端登录时,他将收到一个带有他的设备 ID(在移动设备中)的令牌 - 在请求正文中发送到服务器 - 作为有效负载......
The thing I want to do is for further requests when the client sends his device id in the body (as a convention in my project) and of course the token in the header request, I want to check if the device id and the token's payload are equal or not.我想要做的事情是当客户端在正文中发送他的设备 ID(作为我项目中的约定)以及标头请求中的令牌时的进一步请求,我想检查设备 ID 和令牌的有效负载是否相等。
I did this in a service like this:我在这样的服务中做到了这一点:
public class AuthenticationService
{
public bool IsAuthenticated(HttpRequest req, string deviceId)
{
var token = req.Headers["authorization"];
var handler = new JwtSecurityTokenHandler();
JwtSecurityToken tokenS;
foreach (var stringValue in token)
{
var ss = stringValue.Replace("Bearer ", "");
if (handler.CanReadToken(ss))
{
tokenS = handler.ReadToken(ss) as JwtSecurityToken;
return tokenS.Claims.Any(c => c.Value == deviceId);
}
}
return false;
}
}
And I should inject it in every controller that I want to authorize the user...我应该将它注入到我想要授权用户的每个控制器中......
if (_authenticationService.IsAuthenticated(Request, deviceId))
{
_logger.LogInformation("authorized!");
}
else
{
_logger.LogCritical("unauthorized");
}
I want to know that if there is a more cleaner way of doing this?我想知道是否有更清洁的方法来做到这一点? Something to do in the Startup class when I'm configuring the Authentication:当我配置身份验证时,在 Startup 类中要做的事情:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(
Configuration.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false,
};
});
AddJwtBearer
extension will map the claims in token to user's cliams , you can get the device ID by (if cliam type is deviceId
): AddJwtBearer
扩展会将令牌中的声明映射到用户的 cliams ,您可以通过(如果 cliam 类型为deviceId
)获取设备 ID:
var deviceID= context.HttpContext.User.Claims.Where(x => x.Type == "deviceId").FirstOrDefault().Value;
Then you can use Filter or Middleware to read request body and compare the device ID in reuqest body with the one in User's claim .然后,您可以使用 Filter 或 Middleware 读取请求正文并将 reuqest body 中的设备 ID 与 User's claim 中的设备 ID 进行比较。 For example , if using Filter :例如,如果使用过滤器:
public class CustomActionFilter : ActionFilterAttribute
{
public override async void OnActionExecuting(ActionExecutingContext context)
{
if (context.HttpContext.User.Identity.IsAuthenticated) {
//read request body
var bodyStr = "";
var req = context.HttpContext.Request;
req.EnableBuffering();
req.Body.Position = 0;
using (var stream = new StreamReader(req.Body))
{
bodyStr = await stream.ReadToEndAsync();
}
// here you get device ID from bodyStr ,for example : deviceIDFromReq
var deviceID= context.HttpContext.User.Claims.Where(x => x.Type == "deviceId").FirstOrDefault().Value;
// then compare
if (deviceIDFromReq.Equals(deviceID))
{
context.Result = new BadRequestObjectResult(new
{
status = "error",
description = "deviceID not matched"
});
}
}
base.OnActionExecuting(context);
}
}
Register as global filter :注册为全局过滤器:
services.AddControllers(config =>
{
config.Filters.Add<CustomActionFilter>();
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.