是否可以在没有客户端机密的情况下从 Spring OAuth2 服务器获取 access_token? [英] Is it possible to get an access_token from Spring OAuth2 server without client secret?

查看:19
本文介绍了是否可以在没有客户端机密的情况下从 Spring OAuth2 服务器获取 access_token?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Spring Security 的 OAuth2 服务器实现.我正在尝试使用 OAuth2密码"授权类型从服务器的 /oauth/token 端点获取 access_token,方法是仅提供用户名和密码以及客户端 ID,而不提供客户端密码.只要我在我的 HTTP 请求的 Authorization 标头中提供客户端 ID 和客户端密码,这就可以正常工作:

I am using Spring Security's OAuth2 server implementation. I am trying to get the access_token from the servers' /oauth/token endpoint using the OAuth2 "Password" grant type by only supplying username and password and the client id without the client secret. This works fine as long as I provide the client id and the client secret in the Authorization header of my HTTP request like so:

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

遵循此处的建议:Spring OAuth2 禁用 TokenEndpoint 的 HTTP 基本身份验证,我设法禁用了 /auth/token 端点的 HTTP 基本身份验证.但是当我尝试通过 cURL 获取 access_token 时:

Following the advice here: Spring OAuth2 disable HTTP Basic Auth for TokenEndpoint, I managed to disable HTTP Basic authentication for the /auth/token endpoint. But when I tried to get the access_token via cURL like so:

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

我收到一个 BadCredentialsException 并且可以看到消息:

I got a BadCredentialsException and could see the message:

认证失败:密码与存储值不匹配

Authentication failed: password does not match stored value

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

in my servers' log. At this point I was slightly irritated, because it was my understanding that this message only shows up when there's something wrong with the username and/or password, not the client id and/or secret. After additionally supplying the client secret in the cURL command like so:

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

一切又好了.

那么这是否意味着我必须以一种或另一种方式提供客户端机密才能访问 /auth/token 端点?

So does that mean I have to supply the client secret one way or another to access the /auth/token endpoint?

PS:我知道关于安全性,通过 HTTP 基本身份验证保护此端点通常是一个好主意,但在某些用例中,人们宁愿不这样做.

PS: I am aware of the fact that regarding security it is generally a good idea to protect this endpoint via HTTP Basic authentication, but there are some use cases where one would rather be able to do without.

我似乎找到了一种省略客户端密码的方法.这是我的 OAuth2 服务器配置(注意对 allowFormAuthenticationForClients()autoApprove(true) 的调用):

I seem to have found a way to omit the client secret. Here's my OAuth2 server configuration (notice the calls to allowFormAuthenticationForClients() and 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");
    }

}

编辑二:

这里的问题:Spring安全 OAuth 2.0 - 授权代码授予总是需要客户端机密 与此密切相关,但处理 OAuth2 授权类型授权代码",这会导致与您使用授权类型获得的工作流程不同的工作流程密码".

The question here: Spring Security OAuth 2.0 - client secret always required for authorization code grant is very closely related to this one but deals with the OAuth2 grant type "Authorization Code", which results in a different workflow like the one you get with grant type "Password".

推荐答案

根据规范 (RFC 6749),如果您的应用程序的客户端类型是public,不需要客户端机密.相反,如果客户端类型是机密,则需要客户端机密.

According to the specification (RFC 6749), if the client type of your application is public, a client secret is not required. On the contrary, if the client type is confidential, a client secret is required.

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

If Spring offers an API to set the client type, try to set the client type to public.

这篇关于是否可以在没有客户端机密的情况下从 Spring OAuth2 服务器获取 access_token?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆