【问题标题】:Identity Server 4 - Getting invalid_client errorIdentity Server 4 - 获取 invalid_client 错误
【发布时间】:2017-05-11 10:17:47
【问题描述】:

我是 Identity Server 的新手。我之前没有配置过。但我正在从事的项目需要它。

API 将为 Angular JS 客户端、iOS 应用和 Android 应用提供服务。我们需要实现认证和授权。

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

我已遵循文档并将身份服务器配置如下:

在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 我只想从身份服务器获取访问令牌,然后使用访问令牌进行身份验证和授权。

为此,我正在尝试从 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)

            });

我在服务器端遇到的错误是“未找到客户端标识符”:

1 - 为什么会出现此错误?

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

【问题讨论】:

  • 你在哪里配置用户?您正在使用 grant_type=password 和 username/password 登录。好像用户不存在,
  • 请求没有到达 CustomResourceOwnerPasswordValidator - 所以这意味着身份服务器在到达密码验证器之前抛出了 invalid_client 错误 - @RuardvanElburg

标签: oauth-2.0 openid identityserver3 identityserver4


【解决方案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 的一个 sn-p,其中包含您返回的确切错误作为证据 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 授权类型。我从 IdentityServer 开发人员那里看到的一般建议是对 Web 应用程序和授权代码(或混合)流使用隐式流。你可以在这里读更多关于它的内容: http://docs.identityserver.io/en/release/topics/grant_types.html

【讨论】:

  • 是的,当我包含 client_secret 时它可以工作,但我很困惑。在文档中它说 client_secret 是可选的。 docs.identityserver.io/en/release/endpoints/token.html
  • 请看我更新的答案。 Client 的默认构造函数默认 RequireClientSecret 为 true。如果您不想要求客户端密码,只需将其设置为 false。您是对的,不需要在 ResourceOwner 流身份验证中包含客户端密码。 IdentityServer3 需要它,但 v4 不再需要 IIRC。
猜你喜欢
  • 2020-07-14
  • 2020-01-06
  • 2021-06-29
  • 2020-03-15
  • 1970-01-01
  • 2018-06-03
  • 2020-11-12
  • 2018-06-27
  • 2022-06-23
相关资源
最近更新 更多