第32章 事件

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

活动适用于ELKSeqSplunk等活动商店。

32.1 发出事件

默认情况下不会启用事件 - 但可以在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"));
    }
}

32.2 自定义接收器

我们的默认事件接收器只是将事件类序列化为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包添加到主机以使上述代码有效。

32.3 内置事件

IdentityServer中定义了以下事件:

  • ApiAuthenticationFailureEvent ApiAuthenticationSuccessEvent
    获取内省端点上的成功/失败API身份验证。

  • ClientAuthenticationSuccessEvent ClientAuthenticationFailureEvent
    获取在令牌端点处成功/失败的客户端身份验证。

  • TokenIssuedSuccessEvent TokenIssuedFailureEvent
    获取成功/失败尝试请求身份令牌,访问令牌,刷新令牌和授权码。

  • TokenIntrospectionSuccessEvent TokenIntrospectionFailureEvent
    获取成功的令牌内省请求。

  • TokenRevokedSuccessEvent
    获取成功的令牌吊销请求。

  • UserLoginSuccessEvent & UserLoginFailureEvent
    成功/失败用户登录的快速入门UI引发。

  • UserLogoutSuccessEvent
    获取成功的注销请求。

  • ConsentGrantedEvent ConsentDeniedEvent
    在同意UI中引发。

  • UnhandledExceptionEvent
    获取未处理的异常。

  • DeviceAuthorizationFailureEvent DeviceAuthorizationSuccessEvent
    获取成功/失败的设备授权请求。

32.4 自定义事件

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

您需要从我们的基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; }
}

github地址

原文地址:https://www.cnblogs.com/thinksjay/p/10780460.html