bes*_*art 6 spring spring-security
我正在使用 Spring security 并使用编码器对密码进行编码。
因此,在我的 Spring Security Config 中,我已自动连接
PasswordEncoder passwordEncoder()并将其添加到 中DaoAuthenticationProvider,这是我的 Spring Security 配置
   package it.besmart.easyparking.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor;
import org.springframework.web.servlet.support.RequestDataValueProcessor;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired
    @Qualifier("customUserDetailsService")
    UserDetailsService userDetailsService;
    @Autowired
    CustomSuccessHandler customSuccessHandler;
    @Autowired
    CustomAuthenticationFailureHandler customAuthenticationFailureHandler;
    @Autowired
    DataSource dataSource;
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
        auth.authenticationProvider(authenticationProvider());
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        return authenticationProvider;
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/", "/home", "/user/**").permitAll()
                .antMatchers("/spots/**", "/parks/**", "/floors/**", "/lights/**", "/sensors/**", "/illumination/**",
                        "/occupation/**", "/movement/**", "/map/**", "/include/**")
                .access("hasRole('USER') or hasRole('ADMIN') or hasRole('PARK')").antMatchers("/admin/**")
                .access("hasRole('ADMIN') and hasRole('PARK')").antMatchers("/updatePassword")
                .hasAuthority("CHANGE_PASSWORD_PRIVILEGE").
                and().formLogin().loginPage("/login").successHandler(customSuccessHandler)
                .failureHandler(customAuthenticationFailureHandler).usernameParameter("email")
                .passwordParameter("password").and().rememberMe().rememberMeParameter("remember-me")
                .tokenRepository(persistentTokenRepository()).tokenValiditySeconds(86400).and().csrf().and()
                .exceptionHandling().accessDeniedPage("/Access_Denied");
    }
    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl tokenRepositoryImpl = new JdbcTokenRepositoryImpl();
        tokenRepositoryImpl.setDataSource(dataSource);
        return tokenRepositoryImpl;
    }
    @Bean
    public RequestDataValueProcessor requestDataValueProcessor() {
        return new CsrfRequestDataValueProcessor();
    }
}
当我将数据从 DTO 传递给模型时,我只需执行以下操作
user.setPassword(passwordEncoder.encode(accountDTO.getPassword()));
在我的数据库中,我看到编码的密码,例如$2a$10$vVCWjKltOiYO0nPYT1qYI.z4TSk2QJqViDOqRfmoB6BAgldF4vAmm
但是当我尝试登录时,我得到了
org.springframework.security.authentication.BadCredentialsException: Bad credentials
当我看到日志时,我发现了这个
o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt
我在数据库中的密码字段是 varchar(100) 所以我认为有足够的空间来存储它...如果我用解码后的密码更改数据库中的编码密码,我可以登录...
这是我的 CustoUserDetailsService
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
    @Autowired
    UserRepository repository;
    private final Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class);
    @Override
    @Transactional(readOnly = true)
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;
        try {
            User user = repository.findByEmail(email);
            if (user == null) {
                throw new UsernameNotFoundException("No user found with username: " + email);
            }
            logger.debug("user: " + user.toString());
            return new org.springframework.security.core.userdetails.User(user.getEmail(),
                    user.getPassword(), user.isEnabled(), accountNonExpired, credentialsNonExpired, accountNonLocked,
                    getAuthorities(user));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    private List<GrantedAuthority> getAuthorities(User user) {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority("ROLE_" + user.getUserProfile().getType()));
        // System.out.print("authorities :"+authorities);
        return authorities;
    }
}
由于错误的实例化对象未收到相应字段中的编码密码,该位置的UserDetailsService.loadUserByUsername()方法已引发异常。returnUser
正确的代码如下所示:
...
public UserDetails loadUserByUsername(String username) 
                                      throws UsernameNotFoundException {
  
    UserEntity user = userRepository.findByUsername(username);
    if (user == null)
       throw new UsernameNotFoundException("Bad credentials");
    return new User(
        user.getUsername(), 
        user.getPassword(), // shall to be the already BCrypt-encrypted password
        getAuthorities());
}
一旦BCrypt 哈希和格式不正确,org.springframework.security.authentication.BadCredentialsException: Bad credentials就会抛出该错误。user.getPassword()
密码编码器可以这样注册:
@Autowired
public BCryptPasswordEncoder bCryptPasswordEncoder() {
    return new BCryptPasswordEncoder();
}
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            
     auth
          .userDetailsService(userDetailsService)
          .passwordEncoder(bCryptPasswordEncoder);
}
这就是它的工作原理。
| 归档时间: | 
 | 
| 查看次数: | 21377 次 | 
| 最近记录: |