问题描述
我正在尝试安装IdentiyServer4,但我被授权困住了:调用/ connect / introspect端点会给我错误
IdentityServer4.Validation.ApiSecretValidator:错误:找不到具有该名称的API资源。流产 IdentityServer4.Endpoints.IntrospectionEndpoint:错误:未经授权的API调用自省端点。流产。 客户端是一个网络框架4.7 MVc,并使用IdentityServer3.AccesTokenValidation包
这是我的Identity Server配置
internal class Resources
{
public static IEnumerable<IdentityResource> GetIdentityResources()
{
return new[]
{
new IdentityResources.OpenId(),new IdentityResources.Profile(),new IdentityResources.Email(),new IdentityResource
{
Name = "role",UserClaims = new List<string> {"role"}
}
};
}
public static IEnumerable<ApiResource> GetApiResources()
{
return new[]
{
new ApiResource
{
Name = "electronicinvoice",displayName = "electronicinvoice",Description = "electronicinvoice",Scopes = new List<string> { "electronicinvoice" },ApiSecrets = new List<Secret> {new Secret("XXXXX".Sha256())},UserClaims = new List<string> {"role"}
}
};
}
public static IEnumerable<ApiScope> GetApiScopes()
{
return new[]
{
new ApiScope("electronicinvoice","Access to electronicinvoiceactive api"),};
}
}
客户:
internal class Clients
{
public static IEnumerable<Client> Get()
{
ICollection<string> allowed = GrantTypes.ClientCredentials.Union(GrantTypes.ResourceOwnerPassword).ToList();
return new List<Client>
{
new Client
{
ClientId = "SolutionUpdate",ClientName = "Legal SolutionDOC client",AllowedGrantTypes =allowed,ClientSecrets = new List<Secret> {new Secret("XXXXX".Sha256())},AllowedScopes = new List<string> {"email","openid","profile","electronicinvoice" },}
};
}
}
启动方法
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddInMemoryClients(Clients.Get())
.AddInMemoryIdentityResources(Resources.GetIdentityResources())
.AddInMemoryApiResources(Resources.GetApiResources())
.AddInMemoryApiScopes(Resources.GetApiScopes())
.AddDeveloperSigningCredential()
.AddProfileService<ProfileService>()
.AddCustomTokenRequestValidator<TokenRequestValidator>();
services.AddTransient<IResourceOwnerPasswordValidator,ResourceOwnerPasswordValidator>();
services.AddTransient<IProfileService,ProfileService>();
}
而且,当然是客户端配置
public void Configuration(IAppBuilder app)
{
JwtSecurityTokenHandler.InboundClaimTypeMap.Clear();
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationoptions()
{
Authority = "https://localhost:44389",ClientId = "SolutionUpdate",ClientSecret = "XXXXXX",ValidationMode = ValidationMode.ValidationEndpoint
});
}
var client = new TokenClient("https://localhost:44389/connect/token","SolutionUpdate","XXXXX");
var extra = new Dictionary<string,string> { { nameof(paramAuth.CustomerCode),paramAuth.ToJson() } };
var response = client.RequestClientCredentialsAsync("electronicinvoice",extra).Result;
var token = response.Accesstoken;
return Content(new DTO.GetTokenResponse { Token = token }.ToJson(),"application/json");
但是我无法访问任何用Authorize属性修饰的方法。 我还尝试过像这样直接调用自省端点
var introspectionClient = new IntrospectionClient("https://localhost:44389/connect/introspect","XXXXXX");
var response = introspectionClient.SendAsync(new IntrospectionRequest { Token = accesstoken }).Result;
var isActive = response.IsActive;
var claims = response.Claims;
或邮递员
POST / connect / introspect 授权:基本(带有用户名和密码)和正文 令牌= myaccesstoken
欢迎任何建议 Nb:我加倍使用的密码,它们都是正确的
解决方法
好的,我知道了: 内省端点希望使用Apiscope凭据进行基本身份验证。 此行为在identityserver3中可能不同,或者我在某处缺少配置。
所以我有2个解决方法: -将Apiscope的名称和密码更改为与clientId和password相同的名称 -实现我自己的AuthorizeAttribute,在这种情况下,我将调用自省端点并解析响应。 我将与第二种可能性一起使用,感觉不太“骇人”,而且我担心第一种变通办法会在我设置令牌加密时给我带来麻烦