日志记录是更低级别的“printf”样式 - 事件代表有关IdentityServer中某些操作的更高级别信息。事件是结构化数据,包括事件ID,成功/失败信息,类别和详细信息。这使得查询和分析它们变得容易,并提取可用于进一步处理的有用信息。

活动适用于ELKSeqSplunk等活动商店

发出事件

默认情况下不会启用事件 - 但可以在ConfigureServices方法中进行全局配置,例如:

services.AddIdentityServer(options =>
{
    options.Events.RaiseSuccessEvents = true;
    options.Events.RaiseFailureEvents = true;
    options.Events.RaiseErrorEvents = true;
});

要发出事件,请使用IEventServiceDI容器并调用RaiseAsync方法,例如:

public async Task<IActionResult> Login(LoginInputModel model)
{
    if (_users.ValidateCredentials(model.Username, model.Password))
    {
        // issue authentication cookie with subject ID and username
        var user = _users.FindByUsername(model.Username);
        await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username));
    }
    else
    {
        await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials"));
    }
}

自定义接收器

我们的默认事件接收器只是将事件类序列化为JSON并将其转发到ASP.NET Core日志系统。如果要连接到自定义事件存储,请实现该IEventSink接口并将其注册到DI。

以下示例使用Seq发出事件:

 public class SeqEventSink : IEventSink
{
    private readonly Logger _log;

    public SeqEventSink()
    {
        _log = new LoggerConfiguration()
            .WriteTo.Seq("http://localhost:5341")
            .CreateLogger();
    }

    public Task PersistAsync(Event evt)
    {
        if (evt.EventType == EventTypes.Success ||
            evt.EventType == EventTypes.Information)
        {
            _log.Information("{Name} ({Id}), Details: {@details}",
                evt.Name,
                evt.Id,
                evt);
        }
        else
        {
            _log.Error("{Name} ({Id}), Details: {@details}",
                evt.Name,
                evt.Id,
                evt);
        }

        return Task.CompletedTask;
    }
}

Serilog.Sinks.Seq添加到主机以使上述代码有效。

内置事件

IdentityServer中定义了以下事件:

ApiAuthenticationFailureEvent & ApiAuthenticationSuccessEvent
获取内省端点上成功/失败的API身份验证。
ClientAuthenticationSuccessEvent & ClientAuthenticationFailureEvent
获取在令牌端点处成功/失败的客户端身份验证。
TokenIssuedSuccessEvent & TokenIssuedFailureEvent
获取成功/失败尝试请求身份令牌,访问令牌,刷新令牌和授权码。
TokenIntrospectionSuccessEvent & TokenIntrospectionFailureEvent
获取成功的令牌内省请求。
TokenRevokedSuccessEvent
获取成功的令牌吊销请求。
UserLoginSuccessEvent & UserLoginFailureEvent
成功/失败用户登录的快速入门UI引发。
UserLogoutSuccessEvent
获取成功的注销请求。
ConsentGrantedEvent & ConsentDeniedEvent
在同意UI中引发。
UnhandledExceptionEvent
获取未处理的异常。

自定义事件

您可以创建自己的事件并通过我们的基础架构发出它们。

您需要从我们的基Event派生,类注入活动ID,时间戳等上下文信息。您的派生类可以添加特定于事件上下文的任意数据字段:

public class UserLoginFailureEvent : Event
{
    public UserLoginFailureEvent(string username, string error)
        : base(EventCategories.Authentication,
                "User Login Failure",
                EventTypes.Failure,
                EventIds.UserLoginFailure,
                error)
    {
        Username = username;
    }

    public string Username { get; set; }
}