春季 Oauth2。 DaoAuthenticationProvider 中未设置密码编码器

Posted

技术标签:

【中文标题】春季 Oauth2。 DaoAuthenticationProvider 中未设置密码编码器【英文标题】:Spring Oauth2. Password encoder is not set in DaoAuthenticationProvider 【发布时间】:2014-11-18 17:33:08 【问题描述】:

我对 Spring Oauth 和 Spring Security 还是很陌生。我正在尝试在我的项目中使用 client_credentials 流程。现在我设法使用我自己的 CustomDetailsS​​ervice 以便从我系统中已经存在的数据库中获取 client_id 和密码(秘密)。唯一的问题是我无法更改 AuthorizationServer 使用的 DaoAuthenticationProvider 中的密码编码器 - 它默认设置为 PlaintextPasswordEncoder。我无法配置它,例如 SHAPasswordEncoder。它总是使用明文编码器。我可能不太了解流程,因为我是春天的新手。

这是我的一些代码(没有 DaoAuthenticationProvider 的配置):

SecurityConfig.java

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter 

private static final String RESOURCE_ID = "restservice";

@Override
public void configure(WebSecurity web) throws Exception 
    web.ignoring().antMatchers("/register/**");



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


@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception 
    auth.authenticationProvider(daoAuthenticationProvider());


@Bean
public DaoAuthenticationProvider daoAuthenticationProvider() 
    DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
    daoAuthenticationProvider.setUserDetailsService(userDetailsService());
    daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
    return daoAuthenticationProvider;


@Bean
public PasswordEncoder passwordEncoder() 
    return new ShaPasswordEncoder();


@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter 

    @Autowired
    private MyCustomClientDetailsService myCustomClientDetailsService;

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

    @Bean
    public ResourceServerTokenServices defaultTokenServices() 
        final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setSupportRefreshToken(true);
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    

    @Bean
    public TokenStore tokenStore() 
        return new InMemoryTokenStore();
    

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception 
        clients.withClientDetails(myCustomClientDetailsService);
    

    @Bean
    public MyCustomClientDetailsService detailsService() 
        return new MyCustomClientDetailsService();
    


@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter 

    ...


还有自定义的ClientDetailsS​​ervice类:

public class MyCustomClientDetailsService implements ClientDetailsService 

@Autowired
private UserService userService;

@Override
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException 

    User fan = userService.getFan(clientId);

    if (fan == null) 
        throw new NoSuchClientException("No client with requested id: " + clientId);
     

    BaseClientDetails details = new BaseClientDetails(clientId, restservice, "write", "client_credentials", "USER");

    details.setClientSecret(fan.getEncodedPassword()); 

    return details;


从我的 UserService 获取的 encodedPassword 始终是错误的凭据,因为 DaoAuthenticationProvider 默认设置了 PlaintextPasswordEncoder。

我在那里缺少什么? 是否可以在用于检查凭据的 DaoAuthenticationProvider 中设置密码编码器?还是我必须编写自己的 AuthenticationProvider,才能按照我想要的方式进行检查?

【问题讨论】:

我遇到了同样的问题你找到解决办法了吗? 【参考方案1】:

如果您只想使用另一个 pass 编码器配置 spring 身份验证,请使用此配置。

<bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder"/>

 <authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="authenticationService">
       <password-encoder ref ="encoder" /> 

          <!--   <user-service>
                <user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN"/>
            </user-service> -->
        </authentication-provider>
    </authentication-manager>

注意:- 在创建用户期间,您需要使用相同的密码编码器类加密用户密码。

【讨论】:

我不是在做同样的事情,而是使用基于 Java 的配置。我正在设置 authenticationProvider: auth.authenticationProvider(daoAuthenticationProvider());之前配置为使用 SHAPasswordEncoder。还是我错了? 您可以配置任何密码编码器。请记住,用户密码应使用相同的 passwordEncoder 类编码方法进行加密。 在 XML 配置中我们可以参考另一个 passwordEncoder , 但问题是我尝试在 DaoAuthenticationProvider 中设置编码器,但根本没有设置 - 我调试了它。我知道在创建用户期间我需要使用相同的编码器,但这不是问题。【参考方案2】:

我发现问题的解决方案是在AuthorizationServerConfigurerAdapter上覆盖configure

@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception 
    oauthServer.passwordEncoder(passwordEncoder);

【讨论】:

请注意,我还必须在 WebSecurityConfigurerAdapter 子类的 configure(AuthenticationManagerBuilder auth) 覆盖中设置它,如下所示:auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder) 否则只有 client_secret 被编码,而不是用户的密码。 感谢您的解决方案。研究了几个星期

以上是关于春季 Oauth2。 DaoAuthenticationProvider 中未设置密码编码器的主要内容,如果未能解决你的问题,请参考以下文章

如何在春季oauth2中获取访问令牌

春季 Oauth2。 DaoAuthenticationProvider 中未设置密码编码器

OAuth2用户详细信息未在春季安全(SpringBoot)中更新

Spring安全和角度

如何在春季使用 OIDC 从授权服务器获取所有用户?

Spring OAuth2 - 更改默认签名算法