2

如何通过调用 Web 服务来覆盖现有的 Spring Security 身份验证,当它失败时,需要重定向一些第三方登录页面。

要调用此身份验证 Web 服务,我需要获取一些 ServletRequest 参数,而对于重定向,我需要访问 ServletResponse。

因此,我需要找出一些带有 ServletRequest 和 ServletResponse 参数的身份验证方法。

但是,我仍然没有找到这样的 ProcessingFilter 或 AuthenticationProvider。

根据 Spring Security basic,似乎我必须覆盖与 AuthenticationProvider 相关的身份验证方法。

根据用例,我必须实现 Spring Security Pre-authentication,

但问题是 PreAuthenticatedAuthenticationProvider 相关的 'authenticate' 方法只有 Authentication 参数。

PreAuthenticatedAuthenticationProvider

public class PreAuthenticatedAuthenticationProvider implements
        AuthenticationProvider, InitializingBean, Ordered {

    public Authentication authenticate(Authentication authentication) {}

}

作为解决方案,是否有可能使用AuthenticationFailureHandler的自定义实现?

谢谢。

4

1 回答 1

1

我已经通过以下方式解决了这个问题,

  • 实现自定义 AbstractPreAuthenticatedProcessingFilter

覆盖doFilter方法

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    try { 

        // Get current Authentication object from SecurityContext
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();

        // Call for third party WS when the Authenticator object is null
        if (auth == null) {

            logger.debug("doFilter : Proceed the authentication"); 

            String appId = "My_APP_ID";
            String redirectURL = request.getRequestURL().toString(); 

            // Call for third party WS for get authenticate 
            if (WS_Authenticator.isAuthenticated(appId, redirectURL)) { 

                // Successfully authenticated
                logger.debug("doFilter : WS authentication success");

                // Get authenticated username 
                String userName = WS_Authenticator.getUserName();               

                // Put that username to request
                request.setAttribute("userName", userName);

            } else {

                String redirectURL = WS_Authenticator.getAuthorizedURL();
                logger.debug("doFilter : WS authentication failed");
                logger.debug("doFilter : WS redirect URL : " + redirectURL);

                ((HttpServletResponse) response).setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
                ((HttpServletResponse) response).sendRedirect(redirectURL);

                // Return for bypass the filter chain 
                return;
            }   

        } else {
            logger.debug("doFilter : Already authenticated"); 
        }   

    } catch (Exception e) {
        logger.error("doFilter: " + e.getMessage());            
    }

    super.doFilter(request, response, chain);
    return;
}

覆盖getPreAuthenticatedCredentials方法

@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {

    // Get authenticated username
    String[] credentials = new String[1];
    credentials[0] = (String) request.getAttribute("userName");

    return credentials;
}
  • 实现 CustomAuthenticationUserDetailsS​​erviceImpl

覆盖loadUserDetails方法

public class CustomAuthenticationUserDetailsServiceImpl implements AuthenticationUserDetailsService<Authentication> {

    protected static final Logger logger = Logger.getLogger(CustomAuthenticationUserDetailsServiceImpl.class);

    @Autowired
    private UserDataService userDataService;

    public UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException {

        // Get authenticated username 
        String[] credentials = (String[]) token.getCredentials();
        String userName = credentials[0];

        try {

            // Get user by username
            User user = userDataService.getDetailsByUserName(userName); 

            // Get authorities username             
            List<String> roles = userDataService.getRolesByUserName(userName);          
            user.setCustomerAuthorities(roles);
            return user;

        } catch (Exception e) {
            logger.debug("loadUserDetails: User not found! " + e.getMessage());
            return null;
        }       
    }
}
于 2017-03-03T08:40:18.903 回答