IdentityServer4 API未经授权可调用自省端点

问题描述

我正在尝试安装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,在这种情况下,我将调用自省端点并解析响应。 我将与第二种可能性一起使用,感觉不太“骇人”,而且我担心第一种变通办法会在我设置令牌加密时给我带来麻烦