Java Spring Security OAuth2:通过 POST 接受客户端凭据 [英] Java Spring Security OAuth2: Accept client credentials via POST

查看:135
本文介绍了Java Spring Security OAuth2:通过 POST 接受客户端凭据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个相当基本的 Spring Boot 设置,我已经安装了 Spring Security,并且我已经成功地设置了 OAuth2 来保护我的 API.

I have a fairly basic Spring Boot setup and I have installed Spring Security and I have managed to successfully set up OAuth2 to protect my API.

几天前我遇到了一些麻烦,提出(并回答)了一个关于点击我的>/oauth/token 终点.我很快发现问题在于我试图在我的 POST 请求正文中发送我的客户端凭据,但在 Spring Security 中配置了令牌端点以接受客户端凭据(client_idsecret) 改为通过 HTTP 基本身份验证.

I had some trouble a few days back and asked (and answered) a question with regards to hitting my /oauth/token end point. I soon figured out that the problem was that I was trying to send my client credentials in the body of my POST request but the token end point is configured in Spring Security to accept the client credentials (client_id and secret) via HTTP Basic Auth instead.

我使用 OAuth2 API 的大部分经验都涉及在 POST 请求正文中发送客户端凭据,我想知道是否可以将 Spring Security 配置为以相同方式运行?

Most of my experience with consuming OAuth2 APIs has involved sending client credentials in the body of the POST request and I was wondering if it was possible to configure Spring Security to function in the same way?

我尝试了一些不同的东西但没有成功,比如设置以下配置选项,但我觉得这可能只在配置 OAuth2 客户端时使用:

I've tried a few different things with no success, like setting the following configuration option, but I feel like that might only be used when configuring an OAuth2 client:

security.oauth2.client.clientAuthenticationScheme=form

这是我的授权服务器配置.

This is my Authorization server configuration.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private UserApprovalHandler userApprovalHandler;

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client_id")
                .secret("secret")
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")
                .scopes("read", "write")
                .accessTokenValiditySeconds(600)
                .refreshTokenValiditySeconds(3600);
    }

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

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()")
                .passwordEncoder(this.passwordEncoder);
    }
}

推荐答案

正如@chrylis 在评论中指出的,诀窍是使用 allowFormAuthenticationForClients 方法在配置授权服务器时在 AuthorizationServerSecurityConfigurer 上.就我而言,我的 AuthorizationServerConfig 类中有这个:

As pointed out by @chrylis in the comments, the trick is to use the allowFormAuthenticationForClients method on AuthorizationServerSecurityConfigurer when configuring the authorization server. In my case, I have this in my AuthorizationServerConfig class:

@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
    security.tokenKeyAccess("permitAll()")
            .checkTokenAccess("isAuthenticated()")
            .passwordEncoder(this.passwordEncoder)
            .allowFormAuthenticationForClients();
}

这将允许通过标准参数传递客户端凭据,例如在 POST 请求的正文中(或在查询字符串中),尽管 Spring 更喜欢通过加入 来使用 HTTP 基本身份验证client_idsecret 连同冒号 (:),对结果进行 base-64 编码,以 作为前缀Basic 并将其传递给 Authorization 标头,因此您最终会得到如下内容:

That will allow passing client credentials via standard parameters, such as in the body of the POST request (or in the query string), though Spring prefers using HTTP Basic Auth by joining the client_id and secret together with a colon (<client_id>:<secret>), base-64 encoding the result, prefixing it with Basic and passing that to the Authorization header, so you would end up with something like this:

Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l

这篇关于Java Spring Security OAuth2:通过 POST 接受客户端凭据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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