IdentityServer4.AddScopes创建无效的连接请求URL

时间:2019-08-15 01:20:22

标签: asp.net-core identityserver4

我们已经成功实现了IdentityServer4,它对于两个简单的网站都可以正常运行。但是,当前项目具有一组非常复杂的策略,每个策略都有多个需求。因此,我们在各种控制器操作上都有许多[Authorize(policy: policyname )]属性。

我面临的问题是我已将这些策略中的每一个都添加为范围以减少返回的声明,但是现在初始连接请求失败,并出现HTTP错误404.15-未找到,因为请求的网址太长。

例如为简化起见,减少了长度:https://localhost:44364/connect/authorize?client_id=Jbssa.HRX.Web&redirect_uri=https%3A%2F%2Flocalhost%3A44352%2Fsignin-oidc&response_type=code%20id_token&scope=openid%20profile%20offline_access%20Jbssa.HRX.BulkEventDocumentAttachs%20Jbssa.HRX.BulkEventDocumentDeletes%20Jbssa.HRX.BulkEvents%20Jbssa.HRX.Categories%20Jbssa.HRX.CheckerboardOutputEmployeeHistory....M&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=5.3.0.0

现在我可以减少声明类型名称的长度,但这只是一个停顿。

这是一个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的请求应该类似,不是吗?

https://localhost:44364/connect/authorize?client_id=Jbssa.HRX.Web&redirect_uri=https%3A%2F%2Flocalhost%3A44352%2Fsignin-oidc&response_type=code%20id_token&scope=openid%20profile%20offline_access%20Jbssa.HRX.Categories&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=5.3.0.0

还是我想念/不了解某事?

更新8月16日

我想我理解您在说Ruard的意思,并且理解身份验证与授权的概念。我们有自己的“ PolicyServer”,它定义了我们应用程序的角色/权限。我遇到的问题是IdentityServer 4,当它发出初始连接请求(已读取,不是我们的代码)时,将所有AllowedScopes合并到该连接请求中以确定返回的声明。这些声明可以针对多种事物,例如身份或Api资源,甚至客户和角色也可以附加声明。但是所有这些都根据请求的范围进行过滤。我们有60多个可能的范围可以保护各种资源,我认为当我们通过AddScopes方法注册OpenId时需要定义这些范围(如上所示)。

更具体地说,当我们不包括所有范围时,IdentityServer4会在连接请求中生成此SQL:

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错误。

1 个答案:

答案 0 :(得分:0)

我们更改了客户要求范围的方式,而是将范围的数量减少到几个,并对这些范围应用适当的声明。它增加了访问令牌的大小,从而增加了响应时间,但不足以保证寻找其他解决方案。