如何在 Identity Server 4 中记录生成的访问令牌?
How can I log the generated Access Token in Identity Server 4?
我想知道如何在 IdentityServer 4 中记录生成的 Refresh 和 AccessToken。
目前,我们已经获得了关于 JwtAccessToken 的自定义实现,每当它生成新的访问令牌时,我们都会将其写入 + userId/name 到中央日志系统。对于 Apis(我们有超过 10 个),它总是将所有传入请求 + JwtToken 写入同一个日志系统。因此,我们可以很容易地跟踪用户在那个特定时间做了什么并查看 logs/values。
现在,我们将用 IDSV4 替换该自定义安全实现,但我们找不到在 IDSV4 中记录生成的令牌的方法。
我们知道可以通过await HttpContext.GetAccessTokenAsync()
获取.Net App中的Access Token。但我们不想从所有将与 IDSV 集成的应用程序(.Net、Spas、Apis(客户端凭据))手动发送日志。我们想像以前一样在一个中心位置管理 AccessToken 日志记录。
我看了IDSV4源码TokenEndpoint.cs第120行,LogTokens()
if (response.IdentityToken != null)
{
_logger.LogTrace("Identity token issued for {clientId} / {subjectId}: {token}", clientId, subjectId, response.IdentityToken);
}
if (response.RefreshToken != null)
{
_logger.LogTrace("Refresh token issued for {clientId} / {subjectId}: {token}", clientId, subjectId, response.RefreshToken);
}
if (response.AccessToken != null)
{
_logger.LogTrace("Access token issued for {clientId} / {subjectId}: {token}", clientId, subjectId, response.AccessToken);
}
实际上,他们为实际令牌编写了 TraceLogs。但是我们不想将日志级别更新为 Trace,因为它会淹没我们的日志系统。
所以,我想知道是否可以实现一项功能,以便在 IDSV4 发出 AccessToken 时将生成的令牌写入日志。生成之后有没有办法拦截这些token?
或者我们是否必须在所有客户端生成或刷新 AccessTokens 时手动记录它?
更新:
感谢 sellotape 给了我 DI 的想法。下面是正确的class拦截生成的Token:
public class CustomTokenResponseGenerator : TokenResponseGenerator
{
public CustomTokenResponseGenerator(ISystemClock clock, ITokenService tokenService, IRefreshTokenService refreshTokenService, IResourceStore resources, IClientStore clients, ILogger<TokenResponseGenerator> logger) : base(clock, tokenService, refreshTokenService, resources, clients, logger)
{
}
public override async Task<TokenResponse> ProcessAsync(TokenRequestValidationResult request)
{
var result = await base.ProcessAsync(request);
// write custom loggings here
return result;
}
}
之后,您可以将 IDSV4 中的默认 class 替换为您自定义的 class
services.Replace(ServiceDescriptor.Transient<ITokenResponseGenerator, CustomTokenResponseGenerator>());
有很多地方可以挂钩;一种是通过派生自 DefaultTokenService
.
创建您自己的 ITokenService
实现
覆盖 CreateAccessTokenAsync()
并让它执行:
Token result = await base.CreateAccessTokenAsync(request);
// Your logging goes here...
return result;
启动时在 DI 容器中换入你的版本(确保它是在默认版本已经添加之后):
services.Replace<ITokenService, MyTokenService>();
...你应该准备好了。
顺便说一句,你真的应该记录你的令牌的散列,而不是令牌本身。您仍然可以根据哈希将请求和操作与用户匹配,但至少没有人能够使用日志记录数据来冒充您的任何用户。
我想知道如何在 IdentityServer 4 中记录生成的 Refresh 和 AccessToken。
目前,我们已经获得了关于 JwtAccessToken 的自定义实现,每当它生成新的访问令牌时,我们都会将其写入 + userId/name 到中央日志系统。对于 Apis(我们有超过 10 个),它总是将所有传入请求 + JwtToken 写入同一个日志系统。因此,我们可以很容易地跟踪用户在那个特定时间做了什么并查看 logs/values。
现在,我们将用 IDSV4 替换该自定义安全实现,但我们找不到在 IDSV4 中记录生成的令牌的方法。
我们知道可以通过await HttpContext.GetAccessTokenAsync()
获取.Net App中的Access Token。但我们不想从所有将与 IDSV 集成的应用程序(.Net、Spas、Apis(客户端凭据))手动发送日志。我们想像以前一样在一个中心位置管理 AccessToken 日志记录。
我看了IDSV4源码TokenEndpoint.cs第120行,LogTokens()
if (response.IdentityToken != null)
{
_logger.LogTrace("Identity token issued for {clientId} / {subjectId}: {token}", clientId, subjectId, response.IdentityToken);
}
if (response.RefreshToken != null)
{
_logger.LogTrace("Refresh token issued for {clientId} / {subjectId}: {token}", clientId, subjectId, response.RefreshToken);
}
if (response.AccessToken != null)
{
_logger.LogTrace("Access token issued for {clientId} / {subjectId}: {token}", clientId, subjectId, response.AccessToken);
}
实际上,他们为实际令牌编写了 TraceLogs。但是我们不想将日志级别更新为 Trace,因为它会淹没我们的日志系统。
所以,我想知道是否可以实现一项功能,以便在 IDSV4 发出 AccessToken 时将生成的令牌写入日志。生成之后有没有办法拦截这些token?
或者我们是否必须在所有客户端生成或刷新 AccessTokens 时手动记录它?
更新: 感谢 sellotape 给了我 DI 的想法。下面是正确的class拦截生成的Token:
public class CustomTokenResponseGenerator : TokenResponseGenerator
{
public CustomTokenResponseGenerator(ISystemClock clock, ITokenService tokenService, IRefreshTokenService refreshTokenService, IResourceStore resources, IClientStore clients, ILogger<TokenResponseGenerator> logger) : base(clock, tokenService, refreshTokenService, resources, clients, logger)
{
}
public override async Task<TokenResponse> ProcessAsync(TokenRequestValidationResult request)
{
var result = await base.ProcessAsync(request);
// write custom loggings here
return result;
}
}
之后,您可以将 IDSV4 中的默认 class 替换为您自定义的 class
services.Replace(ServiceDescriptor.Transient<ITokenResponseGenerator, CustomTokenResponseGenerator>());
有很多地方可以挂钩;一种是通过派生自 DefaultTokenService
.
ITokenService
实现
覆盖 CreateAccessTokenAsync()
并让它执行:
Token result = await base.CreateAccessTokenAsync(request);
// Your logging goes here...
return result;
启动时在 DI 容器中换入你的版本(确保它是在默认版本已经添加之后):
services.Replace<ITokenService, MyTokenService>();
...你应该准备好了。
顺便说一句,你真的应该记录你的令牌的散列,而不是令牌本身。您仍然可以根据哈希将请求和操作与用户匹配,但至少没有人能够使用日志记录数据来冒充您的任何用户。