Identity Server 4 身份相关范围请求,但没有 openid 范围
Identity Server 4 Identity related scope requests, but no openid scope
我正在尝试添加自定义 resource/scope,为了测试,我选择它作为电子邮件,但据我所知,它可以是任何值。所以对于我的资源,我有这个:
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] Invalid scope: email
2019-07-05 11:08:00.684 -04:00 [ERR] Request validation failed
我真的不知道我哪里做错了。根据我找到的所有文档和 SO 帖子,这就是它的完成方式。
编辑:有一个内部错误被忽略并导致错误的 List<IdentityResource>
通过。但是,即使解决了这个问题,现在仍然会导致出现不同错误消息的问题:
Identity related scope requests, but no openid scope
编辑 2:
在一些帮助表格 d_f 之后,我意识到我需要更新我的请求,现在看起来像这样:
/connect/authorize?scope=test openid email&response_type=id_token token&nonce=NONCE
我现在获得授权,我可以在声明中看到电子邮件范围。然而,即使我将电子邮件视为一个范围,我也没有在声明中的任何地方看到实际的电子邮件。
电子邮件是标准身份资源。
尝试
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email()
};
如果你想添加自定义的,你可以找到它here
您在 IdentityResource
中添加 IdentityResources.Email()
声明,这意味着 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 快速入门示例:
https://github.com/IdentityServer/IdentityServer4/tree/master/samples/Quickstarts
您可以开始根据代码示例自定义 client/IDS4。
我看到答案需要一些理论背景。
正如您在任何基础工作或原始 specification 中所发现的那样,OpenID Connect 协议变成了 OpenId 和 OAuth 的组合。 OIdC 与第二个兼容,正如您在请求转换期间看到的那样。 OIdC 的新功能是额外的 身份令牌 。 OAuth 引入了 access aka bearer token + refresh token 以获得新的 access一个当现有的过期。所有这些都是关于使用不记名授权 http header 访问 API。新的 身份令牌 代表应用程序的用户 session,而不是 api。
身份服务器 4 中 identity_token
和 access_token
的有效负载相应地由两个单独的词典 IdentityResources
and ApiResources
控制。不幸的是,您不能同时向两者添加范围。但是您可以使用相同的声明定义两个不同的范围。例如:
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
默认情况下针对大小进行了优化,并且在其有效负载中只有 protocol-required 声明。可以从 IdP 的 Userinfo
endpoint 额外请求所有额外声明。要获取 id_token
内的所有用户声明,您可以在 IdSrv 的客户端配置中设置 AlwaysIncludeUserClaimsInIdToken=true
。
我正在尝试添加自定义 resource/scope,为了测试,我选择它作为电子邮件,但据我所知,它可以是任何值。所以对于我的资源,我有这个:
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] Invalid scope: email
2019-07-05 11:08:00.684 -04:00 [ERR] Request validation failed
我真的不知道我哪里做错了。根据我找到的所有文档和 SO 帖子,这就是它的完成方式。
编辑:有一个内部错误被忽略并导致错误的 List<IdentityResource>
通过。但是,即使解决了这个问题,现在仍然会导致出现不同错误消息的问题:
Identity related scope requests, but no openid scope
编辑 2:
在一些帮助表格 d_f 之后,我意识到我需要更新我的请求,现在看起来像这样:
/connect/authorize?scope=test openid email&response_type=id_token token&nonce=NONCE
我现在获得授权,我可以在声明中看到电子邮件范围。然而,即使我将电子邮件视为一个范围,我也没有在声明中的任何地方看到实际的电子邮件。
电子邮件是标准身份资源。
尝试
return new List<IdentityResource>
{
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResources.Email()
};
如果你想添加自定义的,你可以找到它here
您在 IdentityResource
中添加 IdentityResources.Email()
声明,这意味着 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 快速入门示例:
https://github.com/IdentityServer/IdentityServer4/tree/master/samples/Quickstarts
您可以开始根据代码示例自定义 client/IDS4。
我看到答案需要一些理论背景。 正如您在任何基础工作或原始 specification 中所发现的那样,OpenID Connect 协议变成了 OpenId 和 OAuth 的组合。 OIdC 与第二个兼容,正如您在请求转换期间看到的那样。 OIdC 的新功能是额外的 身份令牌 。 OAuth 引入了 access aka bearer token + refresh token 以获得新的 access一个当现有的过期。所有这些都是关于使用不记名授权 http header 访问 API。新的 身份令牌 代表应用程序的用户 session,而不是 api。
身份服务器 4 中 identity_token
和 access_token
的有效负载相应地由两个单独的词典 IdentityResources
and ApiResources
控制。不幸的是,您不能同时向两者添加范围。但是您可以使用相同的声明定义两个不同的范围。例如:
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
默认情况下针对大小进行了优化,并且在其有效负载中只有 protocol-required 声明。可以从 IdP 的 Userinfo
endpoint 额外请求所有额外声明。要获取 id_token
内的所有用户声明,您可以在 IdSrv 的客户端配置中设置 AlwaysIncludeUserClaimsInIdToken=true
。