问题
I was wondering what I am doing wrong here to authenticate a user. I have an application where the user goes through several steps to activate their account, and upon doing so I would like to bypass the login form and take them directly to their dashboard.
Here is what my automated login function looks like:
protected void automatedLogin(String username, String password, HttpServletRequest request) {
try {
// Must be called from request filtered by Spring Security, otherwise SecurityContextHolder is not updated
CustomUserDetailsService udService = new CustomUserDetailsService(userDAO, request);
UserDetails uDetails = udService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(uDetails, password);
token.setDetails(new WebAuthenticationDetails(request));
DaoAuthenticationProvider authenticator = new DaoAuthenticationProvider();
Authentication authentication = authenticator.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (Exception e) {
e.printStackTrace();
SecurityContextHolder.getContext().setAuthentication(null);
}
}
I must use the DaoAuthenticationProvider class as my authentication provider. I have verified that I am getting a UserDetails model containing the correct credentials, ID, authority roles, etc.
When it calls the authenticate method I run into a Null Pointer somewhere along the way in the DaoAuthenticationProvider class:
org.springframework.security.authentication.AuthenticationServiceException at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:109) at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:132) at com.bosch.actions.BaseController.doAutoLogin(BaseController.java:659) . . . Caused by: java.lang.NullPointerException at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:101)
I'm really not sure what is null, as I don't have the source code available.
Edit I was able to find the source code here - https://github.com/SpringSource/spring-security/blob/master/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java
I was able to get around the Null Pointer by explicitly setting the UserDetailsService on the object:
authenticator.setUserDetailsService(udService);
But now I get bad credentials exception when I know the password provided is correct, because I've seen it in the debugger in the UserDetails object set earlier in the code.
org.springframework.security.authentication.BadCredentialsException: Bad credentials at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:87) at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:149)
回答1:
I was able to get the authentication working by piecing together all of the properties defined in the spring bean definition and setting them programmatically on the DaoAuthenticationProvider object. Looking back this seems like it may have been a silly question, but I hope it helps someone!
Corrected Code:
protected void automatedLogin(String username, String password, HttpServletRequest request) {
try {
// Must be called from request filtered by Spring Security, otherwise SecurityContextHolder is not updated
CustomUserDetailsService udService = new CustomUserDetailsService(userDAO, request);
CustomMd5PasswordEncoder passEncoder = new CustomMd5PasswordEncoder();
ReflectionSaltSource saltSource = new ReflectionSaltSource();
saltSource.setUserPropertyToUse("salt");
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
token.setDetails(new WebAuthenticationDetails(request));
DaoAuthenticationProvider authenticator = new DaoAuthenticationProvider();
authenticator.setUserDetailsService(udService);
authenticator.setPasswordEncoder(passEncoder);
authenticator.setSaltSource(saltSource);
Authentication authentication = authenticator.authenticate(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
} catch (Exception e) {
e.printStackTrace();
SecurityContextHolder.getContext().setAuthentication(null);
}
}
来源:https://stackoverflow.com/questions/18006137/how-can-i-programmatically-authenticate-user-with-spring-security-using-daoauthe