【问题标题】:How can I add custom claims to be returned when requesting a token using OpenIddict?如何在使用 OpenIddict 请求令牌时添加要返回的自定义声明?
【发布时间】:2017-03-23 00:07:48
【问题描述】:

我正在构建 ASP.NET Core 1.1 应用程序(跨平台)并尝试(使用 this sample)在请求 /connect/token 端点时向返回的 access_token 添加自定义声明。
我需要的是不仅返回在access_token 中序列化的声明,而且在响应中返回它们,如下所示:

{
 "token_type": "Bearer",
 "access_token": "...",
 "expires_in": 1799,
 "custom_claim": "..."
}

我在互联网上发现我必须使用 AspNet.Security.OpenIdConnect.Server 并写下我的提供者才能做我想做的事情。
使用第一个示例没有简单的方法吗?
我正在使用 OAUth 2.0,授权类型 Password 并且没有 JWT。
不是不使用 JWT 的要求,只是我在 ASP.NET 4.5 中使用过 OAuth

【问题讨论】:

  • 您是否有特定的原因需要该格式?即使在 javascript 中,反序列化返回令牌的有效负载部分也非常简单?只是好奇你为什么希望他们像你的例子一样。
  • @LouisLewis 我没有使用 JWT,所以我认为反序列化不适用,即使我使用了 JWT,我也无法在令牌中返回自定义声明。

标签: oauth-2.0 asp.net-core openiddict


【解决方案1】:

我需要的是不仅返回在 access_token 中序列化的声明,而且在响应中返回它们,如下所示:

虽然我鼓励您将这些声明存储在身份令牌中 - 以便客户端可以以完全标准的方式轻松读取它们,但在 OpenIddict 1.0 和 2.0 RTM 中是可能的。为此,您有 2 个选择:

使用特殊的“公共”属性(在您的授权控制器中,其中创建身份验证票证):

ticket.SetProperty("custom_claim" + OpenIddictConstants.PropertyTypes.String, user.Id);

注意:OpenIddictConstants.PropertyTypes.String 是一个特殊的后缀,表示添加到票证的身份验证属性可以作为令牌响应的一部分公开。如果您希望将声明返回为 JSON 数字或更复杂的 JSON 结构,则可以使用其他常量。

使用事件模型(在 Startup.cs 中):

services.AddOpenIddict()

    // Register the OpenIddict core services.
    .AddCore(options =>
    {
        // ...
    })

    // Register the OpenIddict server handler.
    .AddServer(options =>
    {
        // ...

        options.AddEventHandler<OpenIddictServerEvents.ApplyTokenResponse>(
            notification =>
            {
                if (string.IsNullOrEmpty(notification.Context.Error))
                {
                    var principal = notification.Context.Ticket.Principal;
                    var response = notification.Context.Response;
                    response["custom_claim"] = principal.FindFirst("your_claim_attached_to_the_principal").Value;
                }

                return Task.FromResult(OpenIddictServerEventState.Unhandled);
            });
    })

    // Register the OpenIddict validation handler.
    .AddValidation();

【讨论】:

  • 您好 Kevin,我是 oppeniddict 的新手,在最新版本的 3.0.1 中,此代码已过时,请告诉我们如何在当前版本中传递自定义声明。我已经尝试过了,但它不起作用: options.AddEventHandler(builder => { builder.UseInlineHandler(context => { if (string.IsNullOrEmpty(context.Error)) { var principal = context.Principal; var response = context.Response; response.AddParameter("custom_claim", "test"); } return default; }); });客户端应用未收到自定义声明。
  • @user2507201 嗨。你所拥有的很好,应该可以工作(并且可以在我的机器上工作)。不知道发生了什么。
  • 你是对的,它工作得很好,我的错。谢谢。
【解决方案2】:

好吧,我们通过在 StartupConfigure 方法中使用 OpenIdConnectOptionsEvents 属性来做到这一点> 添加 Open Id Connect 中间件时的类,例如:

            Events = new OpenIdConnectEvents
            {
                OnTicketReceived = n =>
                {
                    //TODO Your logic here to add custom claims via n.Principal.Identities.First().AddClaims();

                    return Task.CompletedTask;
                }
            }

这是您的用例的选项吗?

【讨论】:

    【解决方案3】:

    作为@Pinpoint 在他的openiddict-samples 存储库中的回答,我关注了this article(在Implementing the Connect/Token Endpoint 部分)..
    我从他的回答中发现我正在尝试做的不是标准的,这就是为什么它不是那么明显和容易做到的。
    您需要使用 JWT 并向其添加自定义声明,以便客户端可以对其进行解码并获取声明,而不是通过它自己的响应发送它们。

    【讨论】:

    • 注意:如果您只想在授权服务器和客户端应用程序之间共享声明,请不要使用 JWT 作为访问令牌格式。相反,将OpenIdConnectConstants.Destinations.IdentityToken 目标附加到您的声明并添加scope=openid 以检索身份令牌(根据定义必然是JWT),您将能够自省以检索您需要的声明。
    • @Pinpoint 我想将access_token 连同声明一起退回。
    • 身份令牌是一个单独的令牌 (id_token)。
    • @Pinpoint 抱歉,我不是 JWT 和 OAuth 方面的专家,但是使用 JWT 有什么问题?
    • 没有错。错误是试图从客户端代码中读取访问令牌(不应该这样做,因为它不是令牌的目标受众)。
    猜你喜欢
    • 2019-06-24
    • 2018-11-17
    • 2021-11-14
    • 2019-11-14
    • 2020-01-15
    • 2021-12-01
    • 2019-03-24
    • 2018-09-18
    • 1970-01-01
    相关资源
    最近更新 更多