在Spring安全中使用PasswordEncoder后获得不同的编码密码

问题描述 投票:0回答:1

我正在尝试通过android应用执行身份验证。我基本上是将用户名和密码(未编码)发送到我的其余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个回答
0
投票

我认为您正在对从客户端收到的密码进行编码,并将其硬编码为具有登录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

© www.soinside.com 2019 - 2024. All rights reserved.