具有基本身份验证和自定义 UserDetailsS​​ervice 的 Spring Boot OAuth2

Posted

技术标签:

【中文标题】具有基本身份验证和自定义 UserDetailsS​​ervice 的 Spring Boot OAuth2【英文标题】:Spring Boot OAuth2 with basic authentication and custom UserDetailsService 【发布时间】:2016-05-27 14:34:07 【问题描述】:

我正在尝试配置一个能够完成基本 OAuth2 流程的 OAuth2 服务器(有关示例,请参见 here)。

抱歉问题太长了

我的第一次尝试是能够执行 authorization_code 流程。

我有以下配置:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig
        extends WebSecurityConfigurerAdapter 

    ....

        @Inject
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
            auth
              .userDetailsService(userDetailsService)
              .passwordEncoder(passwordEncoder());
    

...

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
                .formLogin().loginPage("/login").permitAll()
                .and()
                .requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
                .and()
                .authorizeRequests().anyRequest().authenticated();
    

...

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception 
        return super.authenticationManagerBean();
    

我的服务器配置

@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorServerConfig
        extends AuthorizationServerConfigurerAdapter 

    @Inject
    private TokenStore tokenStore;

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

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception 
        endpoints
            .tokenStore(tokenStore)
            .authenticationManager(authenticationManager);
    

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception 
        security
            .allowFormAuthenticationForClients()
            .checkTokenAccess("authenticated()");
    

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception 
        .inMemory()
                .withClient("foo")
                .secret("foo")
                .authorizedGrantTypes("authorization_code","password", "refresh_token")
                .scopes(new String[]  "read", "write" )
    

确实,我的授权代码流程工作正常!当我尝试按如下方式执行密码流程时问题开始:

POST localhost:8200/oauth/token
Content-Type: application/x-www-form-urlencoded
Accept:application/json
Authorization:Basic Zm9vOmZvbw=="
username=admin&password=admin&grant_type=password&scope=read%20write&client_secret=foo&client_id=foo&

我的问题是 Authorization 头被忽略了,不管有没有结果都是一样的,它给了我 access_token 和 refresh_token

如果我尝试如下启用基本身份验证,请启用 ClientUserDetailsS​​ervice,从数据库 JDBC 读取客户端:

public class SecurityConfig
        extends WebSecurityConfigurerAdapter 

    ....

@Bean
public ClientDetailsUserDetailsService   clientDetailsUserDetailsService(ClientDetailsService clientDetailsService)
    // JDBC clientDetailsService
    return new ClientDetailsUserDetailsService(clientDetailsService);



        @Inject
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
            auth
              .userDetailsService(clientDetailsUserDetailsService());
    

...

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception 
    DaoAuthenticationProvider p = new DaoAuthenticationProvider();
    p.setUserDetailsService(userDetailsService);
    p.setPasswordEncoder(passwordEncoder());
    return new ProviderManager(Lists.newArrayList(p));
    //        return super.authenticationManagerBean();
    

    

现在我所取得的成就是让基本身份验证正常工作,但由于基本身份验证现在它是针对 clientid 和 secret 而不是用户的实际凭据完成的,因此我失去了授权代码流

我错过了什么吗?我怎样才能同时拥有两个流程?请帮助,我现在挣扎了几天。

一些类似的问题,但没有任何运气:

problems injecting custom userDetailsService in Spring Security OAuth2 Spring Boot OAuth 2.0 UserDetails user not found

【问题讨论】:

这甚至是如何编译的。 clientDetailsUserDetailsS​​ervice 接受一个参数..当您调用 bean 时,没有参数。困惑的.com 【参考方案1】:

我认为这是因为您为客户端启用了表单身份验证,您使用的是该身份验证而不是 Basic 标头。

public void configure(AuthorizationServerSecurityConfigurer security) throws Exception 
    security
        .allowFormAuthenticationForClients()
        .checkTokenAccess("authenticated()");

取出.allowFormAuthenticationForClients()

【讨论】:

以上是关于具有基本身份验证和自定义 UserDetailsS​​ervice 的 Spring Boot OAuth2的主要内容,如果未能解决你的问题,请参考以下文章

集成 Spring Security:身份验证自定义 UserDetailsS​​ervice

未指定 authenticationScheme,并且没有找到具有默认身份验证和自定义授权的 DefaultChallengeScheme

Spring Security:未调用自定义 UserDetailsS​​ervice(使用 Auth0 身份验证)

Spring Security 自定义 UserDetailsS​​ervice 和自定义 User 类

无法使用用户名/密码登录令牌端点:drf 令牌身份验证和自定义用户模型,Django

Spring Security 4 xml配置UserDetailsS​​ervice身份验证不起作用