如何使用DaoAuthenticationProvider以编程方式使用Spring Security对用户进行身份验证

时间:2013-08-01 23:07:14

标签: java spring authentication spring-security dao

我想知道我在这里做错了什么来验证用户。我有一个应用程序,用户通过几个步骤来激活他们的帐户,这样做我想绕过登录表单并将它们直接带到他们的仪表板。

以下是我的自动登录功能:

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);
        }

    }

我必须使用DaoAuthenticationProvider类作为我的身份验证提供程序。我已经验证我正在获取包含正确凭据,ID,权限角色等的UserDetails模型。

当它调用authenticate方法时,我会在DaoAuthenticationProvider类中的某个地方遇到Null Pointer:

  

org.springframework.security.authentication.AuthenticationServiceException     在   org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:109)     在   org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:132)     在   com.bosch.actions.BaseController.doAutoLogin(BaseController.java:659)   。 。 。引起:java.lang.NullPointerException at   org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:101)

我真的不确定什么是null,因为我没有可用的源代码。

修改 我能够在这里找到源代码 - https://github.com/SpringSource/spring-security/blob/master/core/src/main/java/org/springframework/security/authentication/dao/DaoAuthenticationProvider.java

我能够通过在对象上显式设置UserDetailsS​​ervice来绕过Null指针:

authenticator.setUserDetailsService(udService);

但是当我知道提供的密码是正确的时,我现在得到了错误的凭证异常,因为我已经在代码中早先的UserDetails对象中的调试器中看到了它。

  

org.springframework.security.authentication.BadCredentialsException:   证件不好   org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:87)     在   org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:149)

1 个答案:

答案 0 :(得分:10)

我能够通过将Spring bean定义中定义的所有属性拼凑在一起并在DaoAuthenticationProvider对象上以编程方式设置它来获得身份验证。回顾这看起来似乎是一个愚蠢的问题,但我希望它有助于某人!

更正后的代码:

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);
        }

    }