authentication - 使用身份核心控制用户登录
问题描述
据我所知,具有个人身份验证模式的身份核心使用 JWT 标准进行身份验证。Hense JWT 是无状态的,它不保留任何有关用户登录的数据。现在我想如果用户第二次登录,则使先前生成的令牌无效。因此,我已在此链接中阅读了有关此内容的信息,并尝试节省生成令牌的时间,并将该时间作为自定义声明存储到令牌本身中。我已经达到了以下几点:
[HttpPost("login")]
public async Task<ActionResult> Login([FromBody] User_Login model)
{
...
await this.updateLastLogin(user.Id, now);
...
}
private async Task updateLastLogin(string UserId, DateTime now)
{
localDbContext.TokenTimeStamps.RemoveRange(localDbContext.TokenTimeStamps.Where(tts => tts.UserId == UserId));
localDbContext.TokenTimeStamps.Add(new TokenTimeStamp(){
TimeStamp = now.ToString("yyyyddMMHHmmssfff"),
UserId = UserId,
});
localDbContext.SaveChanges();
dbContext.Users.First(usr => usr.Id == UserId)
.LastLoginDateTime = now;
dbContext.SaveChangesAsync();
}
现在使用这些代码行,我已经保存了时间戳,以便稍后在身份验证步骤中检查它。现在我正在尝试在中间件中完成这项工作。所以我在 Startup.cs 中写了以下内容:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseAuthentication();
using (var serviceScope = app.ApplicationServices.CreateScope())
{
var services = serviceScope.ServiceProvider;
var localDbContext = services.GetService<CollegeLocalDbContext>();
app.Use(async (context, next) =>
{
var authorizationHeader = context.Request.Headers["Authorization"];
if (!string.IsNullOrWhiteSpace(authorizationHeader))
{
Console.WriteLine(authorizationHeader);
var UserId = context.User.Identity.Name;
var LastLoginDateTime = context.User.Claims.FirstOrDefault(clm => clm.Type == "LastLoginDateTime");
Console.WriteLine($"{UserId} - {LastLoginDateTime?.Value}");
if (
true
// || LastLoginDateTime == null || !localDbContext.TokenTimeStamps.Any(tts => tts.TimeStamp == LastLoginDateTime.Value && tts.UserId == UserId)
)
{
context.User = null;
return;
}
}
// Call the next delegate/middleware in the pipeline
await next();
});
}
app.UseAuthorization();
...
}
现在我有一个主要和一个小问题要解决:
Major:我应该如何破坏身份验证工作?我已经测试清空context.User
,但它不会正常工作。
Minor:if (true || ...)
在使用时if()短路的情况下localDbContext
,表示该对象已被处理。那么我的错误在哪里?
解决方案
我可以帮你解决小问题。Configure
不会为每个请求调用该方法。行:var localDbContext = services.GetService<CollegeLocalDbContext>();
将仅在第一次执行。在第二个请求中,只会async (context, next)
触发匿名方法,当然现在您将没有任何localDbContext
设置。
推荐阅读
- google-apps-script - Google Sheet Script:有没有办法在不停止脚本的情况下显示消息?
- javascript - Angular:通知不同组件之间的嵌套属性更改的正确方法
- php - foreach 循环中的 Phpspreadsheet 工作表在 PHP 中不起作用
- javascript - 这些 JavaScript 类定义有缺点吗?
- javascript - 在数组谷歌应用脚本javascript中间推送空白行
- android - 未连接适配器;跳过布局(Recyclerview)
- firebase - 禁用 auth/user-not-found 功能
- flutter - 未来类型递归函数无法正常工作
- express - 在快速边缘迭代数字类型?
- java - 我想使用 java 实现 websocket,但 StompHeaderAccessor 引用的 getSessionAttributes() 函数显示错误