【发布时间】:2019-12-21 13:10:54
【问题描述】:
我们已经成功实现了 IdentityServer4,它适用于两个简单的网站。然而,当前的项目有一套非常复杂的政策,每个政策都有多个要求。因此,我们在各种控制器操作上有许多 [Authorize(policy: policyname)] 属性。
我面临的问题是我已将这些策略中的每一个都添加为范围以减少返回的声明,但现在初始连接请求失败并出现 HTTP 错误 404.15 - 未找到,因为请求 url 太长。
现在我可以减少声明类型名称的长度,但这只是权宜之计。
这是一个 ASP.NET Core 2.2 网站,我在 ConfigureServices 中设置 OpenIdConnect 如下:
services.AddOpenIdConnect(KnownAuthenticationScheme.JbsMainOidc, options =>
{
options.SignInScheme = KnownAuthenticationScheme.JbsMainCookie;
options.Authority = settings.Authority;
options.ResponseType = settings.ResponseType;
options.ClientId = settings.ClientId;
options.ClientSecret = settings.ClientSecret;
options.RequireHttpsMetadata = settings.RequireHttpsMetadata;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.ClaimActions.MapAll();
// add all scopes possible for the website
AddScopes(options.Scope);
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role
};
})
AddScopes 调用如下所示:
static partial void AddScopes(ICollection<string> scopes)
{
scopes.Add(IdentityServerConstants.StandardScopes.OpenId);
scopes.Add(IdentityServerConstants.StandardScopes.Profile);
scopes.Add("offline_access");
foreach (var item in SupportedPolicies.GetList())
scopes.Add(item);
}
因为在配置期间我无法访问请求 URL,所以我无法将范围数量减少到仅针对调用操作定义的策略。
例如:
[Authorize(SupportedPolicies.Categories)]
public partial class CategoriesController : Core.Mvc.ControllerBase
应该只使用“类别”政策要求,因此对 IdSrv4 的请求应该类似于,不是吗?
或者我错过/不理解什么?
8 月 16 日更新
我想我明白你在说什么 Ruard,我了解身份验证与授权的概念。我们有自己的“PolicyServer”,它定义了我们应用程序的角色/权限。我遇到的问题是 IdentityServer 4,当它发出初始连接请求(读取,而不是我们的代码)时,它将所有 AllowedScopes 组合到该连接请求中以确定要返回的声明。这些声明可以针对多个事物、身份或 Api 资源,甚至客户端和角色也可以附加声明。但是所有这些都被请求的范围过滤掉了。我们有超过 60 种可能的范围来保护各种资源,我认为当我们通过 AddScopes 方法注册 OpenId 时需要定义这些范围(见上文)。
更具体地说,当我们不包括所有范围时,此 SQL 是由 IdentityServer4 在连接请求中生成的:
SELECT [api].[Id], [api].[Description], [api].[DisplayName], [api].[Enabled], [api].[Name]
FROM [dbo].[ApiResource] AS [api]
WHERE EXISTS (
SELECT 1
FROM [dbo].[ApiScope] AS [x]
WHERE [x].[Name] IN (N'openid', N'profile', N'Jbssa.HRX') AND ([api].[Id] = [x].[ApiResourceId]))
ORDER BY [api].[Id]
这决定了检查索赔的资源。如果范围不存在,则找不到资源,STS 返回“无效范围”错误。因此,为什么我添加了所有范围,它现在返回 Url Too long 错误。
【问题讨论】:
-
作用域应该定义一个客户端可以访问的功能。例如。 Calendar.Read、Calendar.Write,其中名称与权限无关,而是与可用功能有关。在资源中,您可以添加策略来定义权限。请阅读我的答案here 并查看PolicyServer。
-
解决您的问题的一个非常简单的解决方法是只给出给定客户有权获得的所有范围,而无需客户请求它们。这将消除您的长网址问题。考虑一下你是否愿意接受。
标签: asp.net-core identityserver4