是否有可能从Spring OAuth2服务器获得access_token而无需客户端密钥?

问题描述:

我正在使用Spring Security的OAuth2服务器实现。我试图通过仅提供用户名和密码以及没有客户端密码的客户端ID,使用OAuth2“密码”授权类型从服务器的端点/oauth/token获取access_token。是否有可能从Spring OAuth2服务器获得access_token而无需客户端密钥?

curl -u clientid:clientsecret http://myhost ... -d "grant_type=password&username=user&password=pw&client_id=OAUTH_CLIENT" 

继建议在这里: 这只要我公司提供的客户端ID和我的HTTP请求的Authorization头客户端机密,像这样工作正常Spring OAuth2 disable HTTP Basic Auth for TokenEndpoint,我设法禁用HTTP基本身份验证/auth/token端点。但是,当我试图通过卷曲拿到的access_token像这样:

curl http://myhost ... -d "grant_type=password&username=user&password=pw&client_id=OAUTH_CLIENT" 

我有一个BadCredentialsException,可以看到以下消息:

验证失败:密码不匹配储值

在我的服务器日志中。在这一点上,我有点恼火,因为我的理解是,只有在用户名和/或密码有问题时才显示此消息,而不是客户端ID和/或密码。在cURL命令中额外提供客户端密钥后,如下所示:

curl http://myhost ... -d "grant_type=password&username=user&password=pw&client_id=OAUTH_CLIENT&client_secret=SECRET" 

一切都很好。

那么这是否意味着我必须以某种方式提供客户端密码才能访问/auth/token端点? PS:我知道这样一个事实,就安全性而言,通过HTTP基本认证来保护这个端点通常是一个好主意,但是也有一些用例可以让人不用去做。

编辑:

我似乎已经找到了一种方法省略客户端机密。这里是我的OAuth2服务器配置(通知allowFormAuthenticationForClients()和电话autoApprove(true)):

@Configuration 
@EnableAuthorizationServer 
class OAuth2Config extends AuthorizationServerConfigurerAdapter { 

    private final AuthenticationManager authenticationManager; 

    public OAuth2Config(AuthenticationManager authenticationManager) { 
     this.authenticationManager = authenticationManager; 
    } 

    @Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
     endpoints.authenticationManager(this.authenticationManager); 
    } 

    @Override 
    public void configure(AuthorizationServerSecurityConfigurer oauth) throws Exception { 
     // allows access of /auth/token endpoint without HTTP Basic authentication 
     oauth.allowFormAuthenticationForClients(); 
    } 

    @Override 
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
     clients 
     .inMemory() 
     .withClient("acme") 
     .autoApprove(true) // <- allows for client id only 
     .authorizedGrantTypes("authorization_code", "refresh_token", "password").scopes("openid"); 
    } 

} 

编辑II:

这里的问题:Spring Security OAuth 2.0 - client secret always required for authorization code grant是很密切的关系这一项,但涉及的是OAuth2用户交付式“授权代码“,这会产生与授权类型为”密码“的工作流程不同的工作流程。

根据规范(RFC 6749),如果你的应用程序的客户端类型为公共,不需要客户端机密。相反,如果客户端类型是机密,则需要客户端密钥。

如果Spring提供API来设置客户端类型,请尝试将客户端类型设置为public

+0

接受指向规范。似乎编辑问题中描述的解决方案将客户端类型设置为公开,正如所需。 –

Spring Boot的实现需要传递一个客户机密来进行身份验证。但是,您可以通过创建类型为AuthorizationServerConfigurer的bean并自行配置它来覆盖此设置。This is the link to the documenation...