英文:
Spring Security login failed
问题
使用定制数据源和Spring Security密码编码器,但登录失败。
Spring Boot版本为2.7.0。
我首先注册了一个名为"132456"的用户,密码为"123456",然后尝试登录,但失败了。
然后我创建了一个测试类:打印true。
@Test
public void selectTest() {
UserDetails userDetails = userInfoService.loadUserByUsername("123456");
System.out.println(userDetails);
boolean matches = passwordEncoder.matches("123456", userDetails.getPassword());
System.out.println(matches);
}
Spring Security配置
@EnableWebSecurity
@Configuration
@Slf4j
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration {
@Autowired
UserInfoService userInfoService;
@Autowired
Gson gson;
@Autowired
JwtTokenFilter jwtTokenFilter;
@Autowired
PasswordEncoder passwordEncoder;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
.... 登录URL已经通过
http.formLogin().loginProcessingUrl("/api/login").permitAll()
.successHandler((request, response, authentication) -> {
this.sendMessage(response, authentication);
})
.failureHandler((request, response, exception) ->
jwtTokenFilter.sendError(response, HttpServletResponse.SC_UNAUTHORIZED, "用户名或密码错误"));
http.logout().invalidateHttpSession(true).clearAuthentication(false);
http.rememberMe().disable();
http.csrf().disable();
return http.build();
}
@Bean
DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userInfoService);
authProvider.setPasswordEncoder(passwordEncoder);
return authProvider;
}
}
userServiceImpl
// 使用mybatisplus框架
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
@Autowired
PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UserInfo::getUsername, username);
return getOne(queryWrapper);
}
@Override
public boolean create(UserInfoDTO userInfoDTO) {
userInfoDTO.setPassword(passwordEncoder.encode(userInfoDTO.getPassword()));
return save(BeanUtil.copyProperties(userInfoDTO, UserInfo.class));
}
}
登录成功后,返回令牌。
英文:
Use customized datasource and Spring Security password encoder, but login failed.
Spring Boot version 2.7.0
I first register a user named "132456", passsword "123456", then login, but failed;
Then I create a test class: print true
@Test
public void selectTest() {
UserDetails userDetails = userInfoService.loadUserByUsername("123456");
System.out.println(userDetails);
boolean matches = passwordEncoder.matches("123456", userDetails.getPassword());
System.out.println(matches);
}
Spring Security config
@EnableWebSecurity
@Configuration
@Slf4j
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration {
@Autowired
UserInfoService userInfoService;
@Autowired
Gson gson;
@Autowired
JwtTokenFilter jwtTokenFilter;
@Autowired
PasswordEncoder passwordEncoder;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
.... login url has pass
http.formLogin().loginProcessingUrl("/api/login").permitAll()
.successHandler((request, response, authentication) -> {
this.sendMessage(response, authentication);
})
.failureHandler((request, response, exception) ->
jwtTokenFilter.sendError(response, HttpServletResponse.SC_UNAUTHORIZED, "username or password error"));
http.logout().invalidateHttpSession(true).clearAuthentication(false);
http.rememberMe().disable();
http.csrf().disable();
return http.build();
}
@Bean
DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userInfoService);
authProvider.setPasswordEncoder(passwordEncoder);
return authProvider;
}
}
userServiceImpl
// use mybatisplus framework
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
@Autowired
PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UserInfo::getUsername, username);
return getOne(queryWrapper);
}
@Override
public boolean create(UserInfoDTO userInfoDTO) {
userInfoDTO.setPassword(passwordEncoder.encode(userInfoDTO.getPassword()));
return save(BeanUtil.copyProperties(userInfoDTO, UserInfo.class));
}
}
login success, then return token.
答案1
得分: 1
Omg,我忘了覆盖接口UserDetails
内部方法:isEnabled()
,哈哈哈。花了两个小时找到这个错误。
/**
* 指示用户是否已启用或禁用。禁用的用户无法进行身份验证。
* @return 如果用户已启用,则返回<code>true</code>,否则返回<code>false</code>
*/
boolean isEnabled();
英文:
Omg, I forgot to override the interface UserDetails
inner method: isEnabled()
, Hahahah. Spent two hours finding this bug.
/**
* Indicates whether the user is enabled or disabled. A disabled user cannot be
* authenticated.
* @return <code>true</code> if the user is enabled, <code>false</code> otherwise
*/
boolean isEnabled();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论