Spring Security 5 - 密码迁移

时间:2018-03-12 13:41:43

标签: java spring spring-boot spring-security

这是earlier question的后续行动。

我正在尝试将OAuth2应用程序迁移到Spring Boot 2 / Security 5.根据我之前的问题(和this)中的一条评论,似乎密码的存储格式正在发生变化。

在我原来的(Spring 1.5.9)应用程序中,我明确指定了BCrypt

// AppConfig

   @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

// SecurityConfig

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {


auth.userDetailsService(userService)    
.passwordEncoder(passwordEncoder);
}

这导致错误,密码"看起来不像BCrypt(我之前的问题的原因)。

感谢回复我之前的问题的评论,好像我需要用{bcrypt}为存储的密码添加前缀。我还用:

替换了我的PassowrdEncoder @Bean
PasswordEncoder passwordEncoder =
    PasswordEncoderFactories.createDelegatingPasswordEncoder();

然而,这导致以下错误:

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"

接下来,我尝试将@Bean更改为以下内容:

@Bean
public PasswordEncoder passwordEncoder() {

    String idForEncode = "bcrypt";
    Map encoders = new HashMap<>();
    encoders.put(idForEncode, new BCryptPasswordEncoder());

    encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
    encoders.put("scrypt", new SCryptPasswordEncoder());

    return new DelegatingPasswordEncoder(idForEncode, encoders);

}

这导致了同样的错误。用户创建部分似乎按预期工作。运行以下内容:

    @Bean
    public CommandLineRunner demo(UserRepository repository) {
        return(args) -> {
            OAuthUser user = new OAuthUser();


            user.setFirstName("K");
            user.setLastName("M");
            user.setPassword(passwordEncoder.encode("L"));
            user.setUserName("KLM");

repository.save(user);
        };
    }

会导致用户使用密码{bcrypt}$2a$10$p/W7UV.fkghBRMzuDhh7z.G0uPLze9yFMLarbHdmwinzlqAHrMUQi

但是,用户验证失败。发出此请求:

curl --request POST \
  --url http://web:secret@localhost:8090/oauth/token \
  --header 'content-type: multipart/form-data; boundary=---011000010111000001101001' \
  --form grant_type=password \
  --form username=KLM \
  --form 'pasword =L'

给出&#34;消息&#34;:&#34;没有为id \&#34; null \&#34;&#34;映射的PasswordEncoder;消息。

首先,任何有关问题的建议都会受到赞赏。

其次,关于迁移到新存储格式,我还有另一个问题。这种存储格式,即{id]password,是一种标准或特定于Spring的东西吗?基本上,在过去,如果密码存储为BCrypt,我可能会从C#或其他应用程序验证密码。需要知道的所有应用程序都是如何处理BCrypt标准。这种新的存储格式是否会抑制通过非Spring应用程序验证用户的能力?

感谢。

编辑:

我最终得到了Spring Boot 2 / Security 5来使用OAuth2。虽然我不记得确切的步骤(我一直在处理一些Spring项目),但我发布的是希望我的相关配置作为指导。

确保添加密码编码器bean:

    @Bean
    public PasswordEncoder passwordEncoder() {
return  PasswordEncoderFactories.createDelegatingPasswordEncoder();
        //return new BCryptPasswordEncoder();
    }

对于授权服务器,请确保您同时参考AuthorizationServerSecurityConifgurerClientDetailsServiceConfigurer部分。

  @EnableAuthorizationServer
@Configuration
public class AuthConfig extends AuthorizationServerConfigurerAdapter {

// Some code omitted for brevity

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


    @Override
    public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
        JdbcClientDetailsService details = new JdbcClientDetailsService(appConfig.dataSource());
        details.setPasswordEncoder(passwordEncoder);

        configurer.withClientDetails(details);
    }


    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
        endpoints.tokenStore(tokenStore).accessTokenConverter(converter)
        .userDetailsService(userService)
        .authenticationManager(authenticationManager);
    }

在SecurityConfig中,确保使用AuthenticationManagerBuilder注册它。

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder);
    }

确保配置ResourceServer,包括HttpSecurity端点。

EnableResourceServer
@Configuration
public class ResourceConfig extends ResourceServerConfigurerAdapter {

    private AppConfig appConfig;

    @Autowired
    private ResourceServerTokenServices tokenService;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    public ResourceConfig(AuthenticationManager authenticationManager, AppConfig appConfig) {
        this.authenticationManager = authenticationManager;
        this.appConfig = appConfig;
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("321");
        resources.tokenServices(tokenService);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.headers().frameOptions().disable().and().requestMatchers().and().authorizeRequests()
                .antMatchers("/user/**").hasAuthority("ROLE_ADMIN").antMatchers("/h2/**").permitAll();

    }

我认为@Config类往往最相关。我的UserDetailsS​​ervice实现没有什么特别之处,我认为我甚至没有在这个应用程序中扩展或自定义客户端(在@Config中看到的内容之外)。

0 个答案:

没有答案
相关问题