我已经运行了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/获取open id文档时,我获得了支持范围:
["address","phone","openid","email","profile","api1","offline_access"]
其中没有“sub”范围作为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")
}
}
};
}
}
所以:无论我尝试什么,我都无法设法获得奇怪的“子”范围。
有人可以帮我吗?
答案 0 :(得分: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文档中获取的以下代码段来添加范围:
// 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
答案 1 :(得分:1)
sub
不是范围,而是声明。它包含在openid
范围内(因此也包含在每个身份标记中)。
由于没有配置IdentityServer这样的范围,这也是您收到错误的原因。如果您从请求中删除了sub
范围,则应该可以使用。