【问题标题】:Spring security Oauth2 Resource Owner Password Credentials GrantSpring security Oauth2 资源所有者密码凭证授予
【发布时间】:2014-09-02 05:04:56
【问题描述】:

刚刚在我的 Eclipse IDE 中安装了 spring security oauth2。我尝试实施的服务将由第二方用户通过他们安装的应用程序使用,因此我选择使用密码授予类型。根据我对 Oauth2 的理解,以下请求应该适用于演示 sparklr2 服务,而无需我编码用户名和密码参数。即

POST http://localhost:8080/sparklr2/oauth/token?grant_type=password&client_id=my-trusted-client&scope=trust&username=marissa&password=koala

但我不断得到

<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>

我是否在此请求中遗漏了某些内容,或者我是否需要在 repo 中启用某些内容

【问题讨论】:

  • 甚至尝试过 curl 客户端凭据授权类型,即 curl -X POST -data "client_id=my-trusted-client&grant_type=password&username=marissa&password=koala" localhost:8080/sparklr2/oauth/token 但我仍然遇到同样的错误
  • sparklr2 项目使用的默认 client_id 和 client_secret 是什么。这是我首先应该问的问题。

标签: spring security oauth passwords


【解决方案1】:

Spring OAuth2 似乎不支持无秘密 OAuth2 客户端的密码授予类型。这可能符合 OAuth2 规范:https://www.rfc-editor.org/rfc/rfc6749#section-4.3.2,尽管规范似乎表明并不总是需要客户端身份验证(这对我来说不是很清楚)。

这意味着当使用密码授权类型调用令牌端点时,您需要传入客户端ID和机密(使用基本身份验证),这也意味着如果客户端不使用密码授权,您将无法使用有一个秘密(您可能仍然可以使用隐式流程)。

在 sparklr2 中,my-trusted-client 没有定义秘密,这就是您的呼叫失败的原因。

如果您想查看实际的密码授权类型,可以尝试my-trusted-client-with-secret

curl -u my-trusted-client-with-secret:somesecret "http://localhost:8080/sparklr2/oauth/token?grant_type=password&username=marissa&password=koala"

【讨论】:

  • Thanx...它成功了,客户端凭据。我试过 'curl -u the_client:secret "localhost:8080/sparklr2/oauth/…"' 和 'curl -X -v -d 'client_id=the_client&client_secret=secret&grant_type=client_credentials' -X POST "localhost:8080/sparklr2/oauth/token"' 但无法解决。
  • 查看在 sparklr 中预先配置的客户端,只有一个具有 client_credentials 授权(my-client-with-registered-redirect)但它没有密码。如果您修改源代码并将“client_credentials”添加到 my-trusted-client-with-secret 的 authorizedGrantTypes 列表中,您应该能够使用 curl -u my-trusted-client-with-secret:somesecret 获取令牌“localhost:8080/sparklr2/oauth/…”。
  • @Christophe L 我觉得 spring 应该支持资源所有者的凭证授予而没有秘密。此外,对于此授权类型规范并没有强制要求拥有客户端机密。事实上,当身份验证服务器对客户端具有隐式信任或当用户或客户端未获得机密凭据时,建议使用授权类型是否正确?意味着受信任的客户端应该能够在没有秘密的情况下获取令牌。
  • 另外stackoverflow.com/a/30113674/944600 好像说在不发送客户端密码的情况下有效?
  • 谢谢.. 我想知道如何发送请求以获取令牌
【解决方案2】:

虽然这个问题有点老了,但我想贡献一下我的发现。

确实,对于 Spring OAuth,您需要指定客户端 ID 才能访问令牌端点,但不必为密码授予类型指定客户端 Secret。

下一行是授权服务器客户端的示例,用于没有任何客户端密钥的密码授予类型。您只需将它们添加到扩展 AuthorizationServerConfigurerAdapter 的类中:

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {    
        clients.inMemory()
            .withClient("clientId")
            .authorizedGrantTypes("password")
            .authorities("ROLE_CLIENT")
            .scopes("read");
    }
 }

此外,确实可以在令牌端点中避免 HTTP 基本身份验证,并在我们的 POST 调用中添加我们的 client_id 作为另一个请求参数。

要实现这一点,您只需在与之前相同的类中添加这些行:

@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
    oauthServer.allowFormAuthenticationForClients();
}

现在我们可以通过这种方式调用令牌端点,按照Stormpath webpage中的示例似乎更正确

POST http://localhost:8080/sparklr2/oauth/token?grant_type=password&client_id=clientId&scope=read&username=marissa&password=koala

【讨论】:

    猜你喜欢
    • 2018-05-25
    • 2015-05-30
    • 2017-07-05
    • 2023-04-05
    • 2016-12-31
    • 1970-01-01
    • 2013-11-23
    • 2016-03-03
    • 2014-07-25
    相关资源
    最近更新 更多