【问题标题】:Getting different encoded password after using PasswordEncoder in Spring security在 Spring security 中使用 PasswordEncoder 后获取不同的编码密码
【发布时间】:2020-04-19 08:12:12
【问题描述】:

我正在尝试从 Android 应用执行身份验证。我基本上将用户名和密码(未编码)发送到我的 rest api 端点,即:/api/management/login我正在使用 Retrofit)。之后,我检查用户是否存在,如果存在则返回对象,如果不存在则返回null。我注意到编码的密码与存储在我的数据库中的密码不同,即使初始密码字符串是相同的。我读到 PasswordEncoder 接口正在生成一个随机盐以对密码进行编码。有没有办法让盐独一无二? 这是我的 Spring 安全配置文件:


@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    private UserPrincipalDetailsService userPrincipalDetailsService;

    public SecurityConfiguration(UserPrincipalDetailsService userPrincipalDetailsService) {
        this.userPrincipalDetailsService = userPrincipalDetailsService;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {


            http.csrf()
            .disable()
            .exceptionHandling()
            .authenticationEntryPoint(new Http403ForbiddenEntryPoint() {}).and()
            .authenticationProvider(authenticationProvider())
            .authorizeRequests()
                .antMatchers("/management/*").hasRole("ADMIN")
                .antMatchers("/*").hasRole("ADMIN")
                .antMatchers("/management/professor*").hasRole("ADMIN")
                .antMatchers("/management/absence*").hasRole("ADMIN")
                .antMatchers("/management/room*").hasRole("ADMIN")
                .anyRequest().permitAll()
                .and()
                .formLogin()
                .loginProcessingUrl("/signin").permitAll()
                .loginPage("/login").permitAll()
                .successHandler(mySimpleUrlAuthenticationHandler())
                .failureUrl("/login?error=true")
                .usernameParameter("username")
                .passwordParameter("password")
                .and()
                .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
                .and()
                .rememberMe().userDetailsService(userPrincipalDetailsService).rememberMeParameter("checkRememberMe");
    }

    @Bean
    DaoAuthenticationProvider authenticationProvider(){
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        daoAuthenticationProvider.setUserDetailsService(this.userPrincipalDetailsService);

        return daoAuthenticationProvider;
    }

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

    @Bean
    MySimpleUrlAuthenticationHandler mySimpleUrlAuthenticationHandler() {
        return new MySimpleUrlAuthenticationHandler();
    }
}

有什么建议吗?

【问题讨论】:

    标签: android spring-security retrofit retrofit2 bcrypt


    【解决方案1】:

    我认为您正在对从客户端收到的密码进行编码,并将其硬编码到带有登录 ID 的 SQL 查询中。如果我的假设是正确的,请不要这样做。

    如你所说

    我检查用户是否存在,如果存在则返回对象,如果不存在则返回 null

    不要对密码进行编码并将其连接到 SQL 查询(在 /login API 中)。相反,仅根据登录 ID 检索数据。如果它返回一个对象,那么显然它会返回一个编码密码。现在您需要将已编码的密码与从客户端收到的纯密码进行比较。

    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    
    BCryptPasswordEncoder encoded = BCryptPasswordEncoder();
    boolean matches = encoder.matches("plain password from client", "encoded password here");
    
    if (matches) {
       // successull login
    } else {
       // invalid login credentials
    }
    

    更多信息请参考BCryptPasswordEncoder#matches() SpringBoot doc

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-15
      • 2015-01-07
      • 2019-10-26
      • 2012-01-17
      • 2014-04-23
      • 2016-01-01
      • 1970-01-01
      • 2021-12-12
      相关资源
      最近更新 更多