Java 如何使用 DaoAuthenticationProvider 以编程方式使用 Spring Security 对用户进行身份验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18006137/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I programmatically authenticate user with Spring Security using DaoAuthenticationProvider
提问by rawkfist0215
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.
我必须使用 DaoAuthenticationProvider 类作为我的身份验证提供程序。我已经验证我得到了一个 UserDetails 模型,其中包含正确的凭据、ID、权限角色等。
When it calls the authenticate method I run into a Null Pointer somewhere along the way in the DaoAuthenticationProvider class:
当它调用身份验证方法时,我在 DaoAuthenticationProvider 类中的某个地方遇到了一个空指针:
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)
org.springframework.security.authentication.AuthenticationServiceException at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:109) at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetails3AuthenticationProvider.java:109) ) 在 com.bosch.actions.BaseController.doAutoLogin(BaseController.java:659) 。. . 引起: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.
我真的不确定什么是 null,因为我没有可用的源代码。
EditI 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:
我能够通过在对象上显式设置 UserDetailsService 来绕过空指针:
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.
但是现在当我知道提供的密码正确时,我得到了错误的凭据异常,因为我已经在调试器中的 UserDetails 对象设置中看到了它。
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)
org.springframework.security.authentication.BadCredentialsException: 在 org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:87) 的错误凭证在 org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.authenticate()爪哇:149)
采纳答案by rawkfist0215
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!
我能够通过将 spring bean 定义中定义的所有属性拼凑在一起并以编程方式在 DaoAuthenticationProvider 对象上设置它们来使身份验证工作。回顾这似乎是一个愚蠢的问题,但我希望它对某人有所帮助!
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);
}
}