WebSecurityConfigurerAdapter中配置
@Autowired
private UserDetailsManagerServiceImpl userDetailsManagerService;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.authenticationProvider(authProvider).userDetailsService(userDetailsManagerService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and().csrf().disable()
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage(LOGIN_PAGE_URL)
.loginProcessingUrl(LOGIN_URL)
.failureHandler(authenticationFailureHandler)
.successHandler(authenticationSuccessHandler)
.permitAll()
.and()
.sessionManagement()
.invalidSessionUrl(LOGIN_PAGE_URL)
// 同一用户最大session数
.maximumSessions(1)
// 达到最大数不禁止登录,第二个会挤掉前一个;若设置为true,则第二个人被禁止登录
.maxSessionsPreventsLogin(false)
.expiredUrl(LOGIN_PAGE_URL)
.sessionRegistry(sessionRegistry());
// .and()
// .exceptionHandling()
// .authenticationEntryPoint((request, response, authException) -> response.getWriter().write(new ResponseBean().error(AdminError.ADMIN_ACCESS_DENIED_ERROR).toString()))
// .accessDeniedHandler(accessDeniedHandler());
}
UserDetailsService代码
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Admin admin = null;
// 查询用户信息
if (CommonStringUtils.isPhoneNo(username)) {
// 手机登录
admin = new Admin().selectOne(Wrappers.<Admin>lambdaQuery()
.eq(Admin::getPhone, username));
} else {
admin = new Admin().selectOne(Wrappers.<Admin>lambdaQuery()
.eq(Admin::getUsername, username));
}
if (admin == null) {
throw new UsernameNotFoundException("用户不存在");
}
// 查询用户权限
val permissions = rolePermissionService.selectRolePermissions(admin.getId());
return new ManagerUserDetails(admin, AuthorityUtils.commaSeparatedStringToAuthorityList(permissions));
}
找原因
然而throw new UsernameNotFoundException("用户不存在");
的异常信息无法被截获,debug发现在ProviderManager中for (AuthenticationProvider provider : getProviders()) {
getProviders()有两个,一个是自定义的AuthenticationProvider,一个是DaoAuthenticationProvider。
解决
搜索发现原来是userDetailsService配置方式不正确,改为重写方式一切正常:
@Override
protected UserDetailsService userDetailsService() {
return new UserDetailsManagerServiceImpl();
}
https://github.com/spring-projects/spring-security/issues/4149#issuecomment-490500277
第三点里面有说使用AuthenticationManagerBuilder配置auth.userDetailsService()默认会注册DaoAuthenticationProvider