ASP.NET IdentityServer v4 核心客户端中的通知

Notifications in ASP.NET Core client for IdentityServer v4

在 IdentityServer 3 中,我在通知中使用了 SecurityTokenValidated 事件,通过名称和声明建立我自己的身份。例如,我存储 access_token 以便稍后使用资源所有者工作流访问 n API:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
AuthenticationType = "oidc",

// ...

Notifications = new OpenIdConnectAuthenticationNotifications
{
    SecurityTokenValidated = async n =>
    {
        var nid = new ClaimsIdentity(
          n.AuthenticationTicket.Identity.AuthenticationType,
          "name",
          ClaimTypes.Role);
        nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));
        nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken));
        nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString()));
    }
}
}

在 IdentityServer 4 中,ASP.NET 核心不是通知 属性。 我可以看到有很多自动生成的声明,但我没有得到 access_token 也没有自动设置身份的用户名

我当前在 ASP.NET Core 中的客户端配置如下所示

   app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
        {
            AuthenticationScheme = "oidc",
            SignInScheme = "Cookies",
            Authority = identityServerUri,
            RequireHttpsMetadata = false,
            ClientId = clientId,
            ResponseType = "id_token token",
            Scope =
            {
                "openid profile email warehouseapi"
            },
            GetClaimsFromUserInfoEndpoint = true,
            SaveTokens = true,
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
        });

IdentityServer 4 中的预期方式是什么?

这其实与IdentityServer4无关。 OWIN 和 AspNetCore 变体中的身份验证中间件之间的差异更大。

这些通知现在更正确地命名 Events

您可以使用以下方法做类似的事情:

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
    AuthenticationScheme = "oidc",
    SignInScheme = "Cookies",

    Authority = "https://demo.identityserver.io",
    PostLogoutRedirectUri = "http://localhost:3308/",
    ClientId = "hybrid",
    ClientSecret = "secret",
    ResponseType = "code id_token",
    GetClaimsFromUserInfoEndpoint = true,
    SaveTokens = true,

    Events = new OpenIdConnectEvents
    {
        OnTokenValidated = async n =>
        {

        }
    }
});

你可以找到所有精彩的活动here

您可以使用 TickedReceived 事件来转换声明:

        var oidcOptions = new OpenIdConnectOptions
        {
            ...
            Events = new OpenIdConnectEvents()
            {
                // get access token
                OnTicketReceived = ctx =>
                {
                    // transform claims
                    var access_token = ctx.Ticket.Properties.GetTokenValue("access_token");
                    return Task.FromResult(0);
                }
            }
        };

此外,您不需要将令牌保存为声明,因为当您将 SaveTokens 设置为 true 时,令牌会自动保存在身份验证属性中。要获得令牌,您可以使用 HttpContext.Authentication.GetTokenAsync("<token name>")