【问题标题】:IdentityServer4: what about the "sub" scope?IdentityServer4:“子”范围呢?
【发布时间】:2017-02-07 23:34:23
【问题描述】:

我已经启动了 IdentityServer4。当我现在尝试进行身份验证时,我收到以下错误:

info: IdentityServer4.Hosting.IdentityServerMiddleware[0]
      Invoking IdentityServer endpoint: IdentityServer4.Endpoints.TokenEndpoint for /connect/token
fail: IdentityServer4.Validation.ScopeValidator[0]
      Requested scope not allowed: sub

当我从 /.well-known/openid-configuration/ 获取打开的 id 文档时,我得到了支持范围:

["address","phone","openid","email","profile","api1","offline_access"]

其中没有supported_scope 的“子”范围。

这是完整的配置文件:

{"issuer":"http://localhost:5000","jwks_uri":"http://localhost:5000/.well-known/openid-configuration/jwks","authorization_endpoint":"http://localhost:5000/connect/authorize","token_endpoint":"http://localhost:5000/connect/token","userinfo_endpoint":"http://localhost:5000/connect/userinfo","end_session_endpoint":"http://localhost:5000/connect/endsession","check_session_iframe":"http://localhost:5000/connect/checksession","revocation_endpoint":"http://localhost:5000/connect/revocation","introspection_endpoint":"http://localhost:5000/connect/introspect","frontchannel_logout_supported":true,"frontchannel_logout_session_supported":true,"scopes_supported":["openid","address","phone","openid","email","profile","api1","offline_access"],"claims_supported":["sub","address","phone_number","phone_number_verified","email","email_verified","name","family_name","given_name","middle_name","nickname","preferred_username","profile","picture","website","gender","birthdate","zoneinfo","locale","updated_at"],"response_types_supported":["code","token","id_token","id_token token","code id_token","code token","code id_token token"],"response_modes_supported":["form_post","query","fragment"],"grant_types_supported":["authorization_code","client_credentials","refresh_token","implicit","password"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["RS256"],"token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post"],"code_challenge_methods_supported":["plain","S256"]}

我在启动时尝试了以下操作:

app.UseIdentity();
app.UseIdentityServer();

var allowedScopes = new []{"address","phone","email","profile","api1","offline_access", "sub"};
var identityAuthOptions = new IdentityServerAuthenticationOptions();
identityAuthOptions.AllowedScopes =  allowedScopes;
identityAuthOptions.AutomaticAuthenticate = true;
identityAuthOptions.AutomaticChallenge = true;        
app.UseIdentityServerAuthentication(identityAuthOptions);

我的 IdentityServer 配置如下:

services.AddIdentityServer()
    .AddTemporarySigningCredential()
    .AddAspNetIdentity<ApplicationUser>()
    .AddOperationalStore(options => 
        options.UseSqlite(Configuration.GetConnectionString("PersistedGrants"), 
        builder => builder.MigrationsAssembly(Assembly.GetEntryAssembly().FullName)))
    .AddInMemoryApiResources(Config.GetApiResources())
    .AddInMemoryClients(Config.GetClients())
    .AddTestUsers(Config.GetUsers())
    .AddInMemoryIdentityResources(Config.GetIdentityResources());


services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

Config 类在哪里:

public class Config
    {
        // scopes define the resources in your system
        public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Address(),
                new IdentityResources.Phone(),
                new IdentityResources.OpenId(),
                new IdentityResources.Email(),
                new IdentityResources.Profile()
            };
        }

        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource("api1", "Main API", new[]{ "sub" })
            };
        }

        // clients want to access resources (aka scopes)
        public static IEnumerable<Client> GetClients()
        {
            // client credentials client
            return new List<Client>
            {
                new Client
                {
                    ClientId = "actionCommunity",
                    AllowPlainTextPkce = true,
                    AlwaysSendClientClaims = true,
                    AllowRememberConsent = true,
                    AlwaysIncludeUserClaimsInIdToken = true,
                    AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
                    RedirectUris = {
                        "http://localhost:3333/login-success",
                        "http://localhost:3000/login-success",
                        "http://localhost:3000/auth.html"
                    },
                    AllowAccessTokensViaBrowser = true,

                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    AllowedScopes = {
                        "api1", "sub",
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.OfflineAccess,
                        IdentityServerConstants.StandardScopes.Address,
                        IdentityServerConstants.StandardScopes.Email,
                        IdentityServerConstants.StandardScopes.Phone,
                        IdentityServerConstants.StandardScopes.Profile,
                    },
                    AllowOfflineAccess = true
                }
            };
        }

        public static List<TestUser> GetUsers()
        {
            return new List<TestUser>
            {
                new TestUser
                {
                    SubjectId = "1",
                    Username = "testUser",
                    Password = "testPassword",

                    Claims = new List<Claim>
                    {
                        new Claim("name", "Testuser"),
                        new Claim("website", "https://www.testuser.de")
                    }
                },
                new TestUser
                {
                    SubjectId = "2",
                    Username = "bob",
                    Password = "password",

                    Claims = new List<Claim>
                    {
                        new Claim("name", "Bob"),
                        new Claim("website", "https://bob.com")
                    }
                }
            };
        }
    }

所以:无论我尝试什么,我都无法将奇怪的“子”范围调高。

有人可以帮我吗?

【问题讨论】:

    标签: openid identityserver4


    【解决方案1】:

    您在创建 APiResource 时传递了 claimType。

       public static IEnumerable<ApiResource> GetApiResources()
        {
            return new List<ApiResource>
            {
                new ApiResource("api1", "Main API", new[]{ "sub" })
            };
        }
    

    以下是构造函数的签名:

    public ApiResource(string name, string displayName, IEnumerable<string> claimTypes)
    

    您可以通过引用从 IdentityServer4 文档中获取的以下 sn-p 来添加范围:

    // expanded version if more control is needed
        new ApiResource
        {
            Name = "api2",
    
            // secret for using introspection endpoint
            ApiSecrets =
            {
                new Secret("secret".Sha256())
            },
    
            // include the following using claims in access token (in addition to subject id)
            UserClaims = { JwtClaimTypes.Name, JwtClaimTypes.Email }
            },
    
            // this API defines two scopes
            Scopes =
            {
                new Scope()
                {
                    Name = "api2.full_access",
                    DisplayName = "Full access to API 2",
                },
                new Scope
                {
                    Name = "api2.read_only",
                    DisplayName = "Read only access to API 2"
                }
            }
        }
    

    更多详情请参考以下链接:

    http://docs.identityserver.io/en/release/configuration/resources.html#defining-api-resources

    【讨论】:

    • 好的,我中午试试。此代码 sn-p 是否添加了 sub 声明?这个子声明是什么,它是为了什么?
    • 参考@Scott Brady 关于子声明的评论。您可以通过在范围或资源UserClaims = { JwtClaimTypes.Subject},中设置 UserClaim 来添加它
    【解决方案2】:

    sub 不是范围,而是声明。它包含在openid 范围内(因此包含在每个身份令牌中)。

    由于没有配置 IdentityServer 这样的范围,这也是您收到错误的原因。如果您从请求中删除 sub 范围,它应该可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-20
      • 2019-12-05
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 2018-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多