【问题标题】:Identity Server 4 Identity related scope requests, but no openid scopeIdentity Server 4 与身份相关的范围请求,但没有 openid 范围
【发布时间】:2019-07-08 20:33:32
【问题描述】:

我正在尝试添加一个自定义资源/范围,为了我的测试,我选择了它作为电子邮件,但据我所知,它可以是任何值。所以对于我的资源,我有这个:

return new List<IdentityResource>
{
    new IdentityResources.OpenId(),
    new IdentityResources.Profile(),
    new IdentityResource("email", "Email", new [] { "email" })
    //new IdentityResources.Email()  -- This was tried as well, same error.
};

return new List<ApiResource> { new ApiResource("test", "Test") };

那么对于客户端的作用域如下:

AllowedScopes = new List<string>
{
    "openid", "profile", "email", "test"
}

但是,当我请求带有 http://localhost:5000/connect/authorize?Scope=test email 的令牌时,页面错误并在我的低谷中看到

2019-07-05 11:08:00.681 -04:00 [ERR] 无效范围:电子邮件
2019-07-05 11:08:00.684 -04:00 [ERR] 请求验证失败

我真的不确定我哪里出错了。根据我发现的所有文档和 SO 帖子,这就是它的完成方式。

编辑:有一个内部错误被忽略并导致错误的List&lt;IdentityResource&gt; 被传递。但是,即使解决了这个问题,它现在仍然会导致出现不同错误消息的问题:

身份相关范围请求,但没有 openid 范围

编辑 2:

在 d_f 的一些帮助之后,我意识到我需要更新我的请求,现在看起来像这样:

/connect/authorize?scope=test openid email&response_type=id_token token&nonce=NONCE

我现在获得了授权,并且可以在声明中看到电子邮件范围。但是,即使我将电子邮件视为一个范围,我也没有在声明中的任何地方看到实际的电子邮件。

【问题讨论】:

  • 您的请求错过了openid 范围。协议始终要求的唯一

标签: c# asp.net-core scope resources identityserver4


【解决方案1】:

我看到答案需要一些理论背景。 正如您可以在任何基础工作或原始specification 中找到的那样,OpenID Connect 协议变成了 OpenId 和 OAuth 的组合。 OIdC 与第二个兼容,正如您在请求转换期间看到的那样。 OIdC 的新功能是额外的身份令牌。 OAuth 引入了 access 又名 bearer 令牌 + refresh token 以在现有过期时获得一个新的 access 令牌。所有这些都是关于使用承载授权 http 标头访问 API 的。并且新的 身份令牌 代表应用程序的用户会话,而不是 api。

身份服务器 4 中 identity_tokenaccess_token 的有效负载分别由两个单独的字典 IdentityResourcesApiResources 控制。不幸的是,您不能同时将范围添加到两者中。但是您可以使用相同的声明定义两个不同的范围。例如:

public static IEnumerable<ApiResource> GetApiResources()
{
    return new List<ApiResource>
    {
        new ApiResource
        {
            Name = "test-api",
            Scopes =
            {
                new Scope
                {
                    Name = "test",
                    UserClaims =
                    {
                        JwtClaimTypes.SessionId,
                        JwtClaimTypes.Role,
                        Constants.TenantIdClaimType,
                        JwtClaimTypes.Email,
                        JwtClaimTypes.Locale
                    }
                }
            }
        }
    };
}

public static List<IdentityResource> GetIdentityResources()
{
    // Claims automatically included in OpenId scope
    var openIdScope = new IdentityResources.OpenId();
    openIdScope.UserClaims.Add(JwtClaimTypes.Locale);

    // Available scopes
    return new List<IdentityResource>
    {
        openIdScope,
        new IdentityResources.Profile(),
        new IdentityResources.Email(),
        new IdentityResource(Constants.RolesScopeType, Constants.RolesScopeType,
                    new List<string> {JwtClaimTypes.Role, Constants.TenantIdClaimType})
            {
                Required = true
            }
    };
}

在此示例中,我们添加了在 access_token 作为 test 范围的一部分和在 id_token 作为标准 email 范围的一部分的电子邮件声明的可能性。

此外,我们必须记住,id_token 在默认情况下针对大小进行了优化,并且在其有效负载中仅包含协议所需的声明。可以从 IdP 的Userinfo endpoint 额外请求所有额外的索赔。要获取id_token 中的所有用户声明,您可以在IdSrv 的客户端配置中设置AlwaysIncludeUserClaimsInIdToken=true

【讨论】:

    【解决方案2】:

    电子邮件是一种标准的身份资源。

    试试

    return new List<IdentityResource>
    {
      new IdentityResources.OpenId(),
      new IdentityResources.Profile(),
      new IdentityResources.Email()
    }; 
    

    documentation

    如果要添加自定义,可以找here

    【讨论】:

    • 我不认为这是问题所在,我可以将其切换为任何名称,我也会遇到同样的问题。
    • 身份验证请求中缺少客户端 ID。您的代码中是否也缺少它,或者您只是将其删除以保持问题清洁?
    • 我更新了我的问题,我解决了为什么会发生该特定错误,但现在已经取而代之的是另一个错误。另外,身份验证请求是什么意思?您说哪个函数缺少 id,我会检查一下?
    • 您的授权请求应该包含 client_id localhost:5000/connect/authorize?client_id={yourClientId}&scope=test 电子邮件,但现在我看到了您更新的问题,我认为它会是别的东西。我以前从未见过这个错误,必须检查一下。
    • @Bojan 当您不请求 openid 范围时,协议会降级为 oauth。没关系,除非您请求任何身份范围——openid connect 添加的扩展
    【解决方案3】:

    您在IdentityResource 中添加IdentityResources.Email()claim,这意味着id_token 将包含用户的电子邮件信息。您可以使用https://jwt.io/ 等在线工具对id_token(不是访问令牌)进行解码,以检查返回的声明。

    您还可以在客户端配置中将AlwaysIncludeUserClaimsInIdToken 设置为true 以查看它是否包含电子邮件声明:

    new Client
    {
        ClientId = "mvc",
        ClientName = "MVC Client",
        AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
    
        ....
    
        ....
        AlwaysIncludeUserClaimsInIdToken = true,
        AllowedScopes =
        {
            IdentityServerConstants.StandardScopes.OpenId,
            IdentityServerConstants.StandardScopes.Profile,
            "api1",
            IdentityServerConstants.StandardScopes.Email,
        },
        AllowOfflineAccess = true
    },
    

    此外,IdentityServer 4 Quickstart Samples 有不同种类(身份验证流程):

    https://github.com/IdentityServer/IdentityServer4/tree/master/samples/Quickstarts

    您可以根据代码示例开始自定义客户端/IDS4。

    【讨论】:

      猜你喜欢
      • 2020-03-18
      • 1970-01-01
      • 2021-10-03
      • 2019-06-25
      • 2017-08-09
      • 2016-04-28
      • 1970-01-01
      • 2021-08-07
      • 2021-01-04
      相关资源
      最近更新 更多