在Spring Security中实现自定义身份验证

时间:2016-04-05 02:55:59

标签: java spring spring-security

我想就Spring Security中的问题向您寻求帮助。 我有一个要求,我必须根据用户选择的选项验证登录凭据。选项1将通过第三方服务验证登录用户。选项2是使用数据库身份验证级别的正常验证。我该如何实现呢?

1 个答案:

答案 0 :(得分:10)

  

一般策略

  1. 提供org.springframework.security.authentication.AuthenticationProvider的自定义实现,将身份验证委派给相应的后端(第三方服务,另一个AuthenticationProvider等)。
  2. 将用户选择的选项传递给自定义AuthenticationProvider,使其能够选择正确的身份验证后端。
  3. 将自定义AuthenticationProvider配置为默认身份验证提供程序。
  4.   

    第1步:实施AuthenticationProvider

    AuthenticationProvider是具有单个方法的接口。因此,自定义实现可能如下所示:

    class DelegatingAuthenticationProvider implements AuthenticationProvider {
      @Autowired
      private ThirdPartyAuthenticationService service;
    
      @Autowired
      @Qualifier("anotherAuthenticationProvider")
      private AuthenticationProvider provider;
    
      @Override
      public Authentication authenticate(final Authentication authentication) throws AuthenticationException {
        // Get the user selection.
        String selection = (String) authentication.getDetails();
    
        // Take action depending on the selection.
        Authentication result;
        if("ThirdParty".equals(selection)) {
          // Authenticate using "service" and generate a new
          // Authentication "result" appropriately.
        }
        else {
          // Authenticate using "provider" and generate a new
          // Authentication "result" appropriately.
        }
    
        return result;
      }
    }
    
      

    第2步:将用户选择传递给AuthenticationProvider

    上面的AuthenticationProvider实现从details对象的Authentication属性中选择用户选择。据推测,必须从HttpServletRequest中选择用户并在调用Authentication之前添加到AuthenticationProvider对象。这意味着,在调用Authentication之前,需要调用另一个可以访问HttpServletRequestAuthenticationProvider对象的组件。

    Authentication对象由AbstractAuthenticationProcessingFilter的实现创建。此类有一个名为attemptAuthentication的方法,它接受HttpServletRequest对象并返回Authentication个对象。因此,这似乎是实施所需内容的良好候选者。对于基于用户名密码的身份验证,实现类为UsernamePasswordAuthenticationFilter。此类返回UsernamePasswordAuthenticationToken的新实例,该实例是Authentication的实现。因此,扩展UsernamePasswordAuthenticationFilter的类应该足够了。

    class ExtendedUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
      @Override
      public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        ...
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, password);
        authentication.setDetails(obtainUserSelection(request));
    
        ...
    
        return authentication;
      }
    }
    

    obtainUserSelection是一种私有方法,可以让用户从请求中选择。

      

    第3步:配置

    在Spring Security配置中配置AuthenticationProvider和过滤器实现。具体步骤将根据是使用XML还是Java配置而有所不同。

相关问题