【发布时间】:2015-06-28 20:20:29
【问题描述】:
我正在使用 DaoAuthenticationProvider 进行身份验证,但是当我提交表单时,super.authenticate(authentication) 调用了两次 loadUserByUsername,它最初会抛出 BadCredentialsException,然后在下次成功登录时
如果我不使用密码编码器,这个过程可以正常工作,但是当我使用它时 loadUserByUsername 方法被调用了两次。
下面是我的代码:
安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("authenticationProvider")
AuthenticationProvider authenticationProvider;
@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.authenticationProvider(authenticationProvider)
.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/**")
.access("hasRole('ROLE_ADMIN')").and().formLogin()
.loginPage("/login").failureUrl("/login?error")
.usernameParameter("username").passwordParameter("password")
.and().logout().logoutSuccessUrl("/login?logout").and().csrf()
.and().exceptionHandling().accessDeniedPage("/403");
}
}
身份验证类
@Component("authenticationProvider")
public class LimitLoginAuthenticationProvider extends DaoAuthenticationProvider {
@Autowired
@Qualifier("userDetailsService")
@Override
public void setUserDetailsService(UserDetailsService userDetailsService) {
super.setUserDetailsService(userDetailsService);
}
@Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
try {
System.out.println("inside authenticate");
Authentication auth = super.authenticate(authentication);
return auth;
} catch (BadCredentialsException be) {
System.out.println("First call comes here ");
throw be;
} catch (LockedException e) {
throw e;
}
}
}
MyUserdetailsService 类实现 UserDetailsService
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserDao userDao;
/* below method is called twice if I am using passwordencoder,
initially authentication fails and then again immediately
on second call authentication succeed */
@Transactional(readOnly=true)
@Override
public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
com.mkyong.users.model.User user = userDao.findByUserName(username);
List<GrantedAuthority> authorities = buildUserAuthority(user.getUserRole());
return buildUserForAuthentication(user, authorities);
}
private User buildUserForAuthentication(com.mkyong.users.model.User user, List<GrantedAuthority> authorities) {
MyUserDetails myUserDetails = new MyUserDetails (user.getUsername(), user.getPassword(), user.isEnabled(), user.isAccountNonExpired(), user.isAccountNonLocked(), user.isCredentialsNonExpired(), user.getEmailId(),authorities);
return myUserDetails;
}
private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles) {
Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
// Build user's authorities
for (UserRole userRole : userRoles) {
setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
}
List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);
return Result;
}
}
请帮帮我。我相信 SecurityConfig 类需要进行一些更改,但我无法弄清楚。
【问题讨论】:
-
我可以看看,但你必须把它放在
github上让我看看。可以有很多东西要看。你的XML configuration。你能创建一个示例项目吗? -
@java_dude。好的,我会把我的项目放在 github 上。
-
@java_dude 是否还有其他地方可以直接复制我的项目并粘贴。 Github 发现有点困难
-
查看此文档以获取
githubhttps://guides.github.com/activities/hello-world/。如果您仍然觉得困难,请将其发送到您的google drive。与public分享并在此处提供链接,我将访问它并将其放在github上。 -
@java_dude 我已经提交了文件,同样的 url 是 link
标签: java spring-mvc spring-security