Reputation: 5233
How can I override the existing Spring Security authentication by invoking a Web Service and when it's failed, need to redirect some third party login page.
For calling this authentication web service, I need to get some ServletRequest parameter and for redirection, I need to access the ServletResponse.
Therefore I need to find out some Authentication method with ServletRequest and ServletResponse parameters.
But still, I failed to find out such a ProcessingFilter or AuthenticationProvider.
According to Spring Security basic it seems I have to override the AuthenticationProvider related authenticate method.
According to use case, I have to implement the Spring Security Pre-authentication,
but the issue is PreAuthenticatedAuthenticationProvider related 'authenticate' method only having the Authentication parameter.
PreAuthenticatedAuthenticationProvider
public class PreAuthenticatedAuthenticationProvider implements
AuthenticationProvider, InitializingBean, Ordered {
public Authentication authenticate(Authentication authentication) {}
}
As solution, is there any possibility to use custom implementation of AuthenticationFailureHandler ?
Thanks.
Upvotes: 2
Views: 2143
Reputation: 5233
I have got resolved the issue as following manner,
Override the doFilter method
@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;
}
Override the getPreAuthenticatedCredentials method
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
// Get authenticated username
String[] credentials = new String[1];
credentials[0] = (String) request.getAttribute("userName");
return credentials;
}
Override the loadUserDetails method
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;
}
}
}
Upvotes: 1