IdentityServer 4在登录/刷新令牌时获取时间戳

Posted

技术标签:

【中文标题】IdentityServer 4在登录/刷新令牌时获取时间戳【英文标题】:IdentityServer 4 get timestamp while login/refresh token 【发布时间】:2020-02-14 00:40:18 【问题描述】:

我们正在使用identity server 4 来保护 api/资源。要求之一是跟踪用户活动,这意味着用户上次使用 api 的时间(未登录但已使用)。由于我们有 30 多个 api,我们认为一旦令牌通过 identity server 验证,拦截此验证过程/事件以在数据库中注册最后一个活动日期会更容易。

我的问题是,每次用户想要访问 api 时,这种验证是否真的发生在身份服务器级别?

是否有办法获取此验证时间戳以将其保存在数据库中的某个位置?

谢谢

【问题讨论】:

我认为这是一个dublicate 的问题。 @d_f,是的,但是那个副本的答案仍然不符合我的需要。如果您检查该答案,您会发现它应该在每个 api 中实现。这是一个开销!但是感谢您的提示! 原题下有几个cmet,全部收集起来,效果最好。答案本身可能不是那么完美,但是您可以将自己的答案放在附近并收集选票 【参考方案1】:

我自己解决了这个问题。我深入研究了 ID-Server 事件,并找到了一种以集中方式处理事件的好方法。所以这个实现只在 ID-Server 项目中。

身份服务器 4 公开了一些可用于跟踪用户活动的事件(例如:令牌颁发成功、令牌颁发失败、登录失败等...)

有关活动的更多信息,请link

在身份服务器项目中,我添加了IEventSink 接口的实现。此接口对事件的持久性进行建模并提供一种方法:PersistAsync

这里是cs类:

public class IdentityServerEventSink : IEventSink

        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly UserManager<IdentityUser> _userManager;

        public IdentityServerEventSink(IHttpContextAccessor httpContextAccessor,
                                       UserManager<IdentityUser> userManager)
        
            _httpContextAccessor = httpContextAccessor;
            _userManager = userManager;
        

        public async Task PersistAsync(Event @event)
        
            if (@event.Id.Equals(EventIds.ClientAuthenticationFailure) || @event.Id.Equals(EventIds.TokenIssuedSuccess) || @event.Id.Equals(EventIds.TokenIssuedFailure))
            
                Identity user = null;

                try
                
                    user = await _userManager.GetUserAsync(_httpContextAccessor.HttpContext.User);

                    if (user != null)
                    
                       // do stuff
                    
                
                catch (Exception ex)
                
                  // handle exception
                
            
        

通过 DI 我正在注入 IHttpContextAccessor,因此您需要在服务配置中添加此行:

services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

这一行将 IEventSink 实现包含在容器中:

services.AddTransient<IEventSink, IdentityServerEventSink>();

希望这会有所帮助!

【讨论】:

以上是关于IdentityServer 4在登录/刷新令牌时获取时间戳的主要内容,如果未能解决你的问题,请参考以下文章

IdentityServer4 刷新令牌为空

外部登录后应该在 IdentityServer 中使用哪个令牌?

如何测试我的令牌是不是使用 IdentityServer4 刷新?

刷新 IdentityServer4 客户端中的访问令牌

带有存储在 cookie 中的刷新令牌的 SPA - 如何使用 IdentityServer4 进行配置?

页面刷新时不存在授权标头