イベント

ログはより低レベルの "printf"スタイルですが、イベントはIdentityServerの特定の操作に関するより高いレベルの情報を表します。イベントは構造化されたデータで、イベントID、成功/失敗情報、カテゴリ、詳細が含まれます。これにより、それらを照会および分析し、さらなる処理に使用できる有用な情報を抽出することが容易になります。

イベントは、ELK、Seq、Splunkなどのイベントストアでうまく機能します。

Emitting events

イベントはデフォルトで有効になっていませんが、ConfigureServicesメソッド内でグローバルに設定することができます。例:

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

イベントを発生させるにIEventServiceは、DIコンテナから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
未処理の例外に対して発生します。
DeviceAuthorizationFailureEvent & DeviceAuthorizationSuccessEvent
Gets raised for successful/failed device authorization requests.

カスタムイベント

あなた自身のイベントを作成し、私たちのインフラを介してそれらを放出することができます。

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; }
}