首页 文章

Identity Server 4 - 获取invaid_client错误

提问于
浏览
3

我是Identity Server的新手 . 我以前没有配置它 . 但我需要它为我正在进行的项目 .

该API将为Angular JS Client,iOS App和Android App提供服务 . 我们需要实现身份验证和授权 .

Note: 我正在尝试在同一个Web API项目中配置Identity Server和我的API .

我已按照文档并配置Identity Server,如下所示:

在startup.cs中,在 ConfigureServices()

services.AddTransient<IProfileService, CustomProfileService>();
        services.AddTransient<IResourceOwnerPasswordValidator, CustomResourceOwnerPasswordValidator>();



        services.AddIdentityServer()
            .AddTemporarySigningCredential()
            // add the resources that need to be secured
            .AddInMemoryApiResources(IdentityServerConfig.Resources.GetApiResources())
            // add the clients that will be access the ApiResources
            .AddInMemoryClients(IdentityServerConfig.Clients.GetClients());

CustomProfileServiceCustomResourceOwnerPasswordValidator 与此答案相同:https://stackoverflow.com/a/35306021/1910735

Configure()

// as this API will also be acting as an
        app.UseIdentityServer();


        // now setup the Identity Server client, this API will also be the client 

        app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = "http://localhost:44337",
            RequireHttpsMetadata = false,


            ApiName = "obApi"
        });

这是 GetClients()

public static IEnumerable<Client> GetClients()
    {
        var clients = new List<Client>();



        var websiteGrants = new List<string> { GrantType.ResourceOwnerPassword };
        var secret = new Secret("secret".Sha256());

        var websiteClient = new Client()
        {
            // we will be using Angular JS to access the API - so naming it js
            ClientId = "js",

            // just a human friendly name
            ClientName = "JavaScript Client",

            // set to GrantType.ResourceOwnerPassword - because using Username/Password to login
            AllowedGrantTypes = websiteGrants, 

            // secret for authentication
            //TODO: Change the secret 
            ClientSecrets = { secret },

            // we need to access the fhApi from Angular JS front-end 
            // fhApi is defined in Resources file as an API Resource
            AllowedScopes = { "obApi" }
        };


        clients.Add(websiteClient);

        return clients;
    }

这是 GetApiResources()

public static IEnumerable<ApiResource> GetApiResources()
    {
        // e.g. if we want to protect an API called api1 - then we will add it here
        // these values are hard coded for now - but we can get from DB, config file etc.

        return new List<ApiResource>
                        {
                            new ApiResource("obApi", "Order2Bite API")
                        };
    }

现在因为我想使用Angular JS,iOS和Android我想从Identity Server获取Access Token,然后使用Access Token进行身份验证和授权 .

为此,我试图从JS客户端访问 /connect/token

但是我收到了 invalid_client 错误 .

var user = { client_id: "js", grant_type: 'password', username: "testuser", password: "testpasswrd", scope: 'obApi' };

        var urlEncodedUrl = {
            'Content-Type': 'application/x-www-form-urlencoded',
        };

        this.$http({
            method: 'POST', url: "http://localhost:44337/connect/token",
            headers: urlEncodedUrl,
            data: user,

        })
            .then(data => {
                console.log(data)
            },
            data => {
                console.log(data)

            });

enter image description here

我在服务器端得到的错误是' No client identifier found':
enter image description here

1 - 为什么我收到此错误?

2 - 由于我需要在JS,Android和iOS中以编程方式获取令牌,我需要使用 /connect/token ,我对此是否正确?我在正确的道路上吗?

1 回答

  • 1

    invalid_client错误通常表示客户端ID或客户端密钥不正确 . 在这种情况下,您不会在对IdentityServer的请求中包含客户端密钥 . 在您的请求中添加“client_secret:'secret'”

    更新数据:

    var user = { client_id: "js", client_secret: "secret", grant_type: 'password', username: "testuser", password: "testpasswrd", scope: 'obApi' };
    

    或者,您不能在客户端配置中要求ClientSecret

    var websiteClient = new Client()
    {
        // we will be using Angular JS to access the API - so naming it js
        ClientId = "js",
    
        // just a human friendly name
        ClientName = "JavaScript Client",
    
        // set to GrantType.ResourceOwnerPassword - because using Username/Password to login
        AllowedGrantTypes = websiteGrants,
    
        // secret for authentication
        //TODO: Change the secret 
        ClientSecrets = { secret },
    
        // Disable client secret validation
        RequireClientSecret = false,
    
        // we need to access the fhApi from Angular JS front-end 
        // fhApi is defined in Resources file as an API Resource
        AllowedScopes = { "obApi" }
    };
    

    下面是IdentityServer4 ClientSecretValidator.cs的一个片段,其中包含您作为证据返回的确切错误https://github.com/IdentityServer/IdentityServer4/blob/release/src/IdentityServer4/Validation/ClientSecretValidator.cs

    var parsedSecret = await _parser.ParseAsync(context);
    if (parsedSecret == null)
    {
        await RaiseFailureEvent("unknown", "No client id found");
    
        _logger.LogError("No client identifier found");
        return fail;
    }
    

    关于为JS,Android和iOS获取令牌的第二个问题,您可能需要考虑将为每个场景使用哪种OpenID Grant类型 . 我从IdentityServer开发人员看到的一般建议是使用Implicit flow for web applications和Authorization Code(或Hybrid)Flow . 你可以在这里阅读更多相关信息:http://docs.identityserver.io/en/release/topics/grant_types.html

相关问题