Created
May 7, 2015 09:07
-
-
Save leon/182f2a221341411f7d1a to your computer and use it in GitHub Desktop.
WIP sso pre auth filter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package se.radley.security; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.boot.autoconfigure.security.SecurityProperties; | |
import org.springframework.cloud.security.oauth2.sso.OAuth2SsoProperties; | |
import org.springframework.security.authentication.AuthenticationDetailsSource; | |
import org.springframework.security.authentication.AuthenticationManager; | |
import org.springframework.security.core.Authentication; | |
import org.springframework.security.core.AuthenticationException; | |
import org.springframework.security.oauth2.client.OAuth2RestTemplate; | |
import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; | |
import org.springframework.security.oauth2.common.OAuth2AccessToken; | |
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; | |
import org.springframework.security.oauth2.provider.OAuth2Authentication; | |
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; | |
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetailsSource; | |
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; | |
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter; | |
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; | |
import org.springframework.security.web.util.matcher.RequestMatcher; | |
import org.springframework.stereotype.Component; | |
import org.springframework.util.Assert; | |
import javax.inject.Inject; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.stream.Collectors; | |
@Component | |
public class OAuthSsoTryAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter { | |
private static final Logger log = LoggerFactory.getLogger(OAuthSsoTryAuthenticationFilter.class); | |
private OAuth2RestTemplate restTemplate; | |
private ResourceServerTokenServices tokenServices; | |
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new OAuth2AuthenticationDetailsSource(); | |
private List<RequestMatcher> ignoreMatchers = new ArrayList<>(2); | |
@Inject | |
public OAuthSsoTryAuthenticationFilter(OAuth2RestTemplate restTemplate, ResourceServerTokenServices tokenServices, OAuth2SsoProperties ssoProperties, SecurityProperties securityProperties) { | |
this.restTemplate = restTemplate; | |
this.tokenServices = tokenServices; | |
setAuthenticationManager(new NoopAuthenticationManager()); | |
setAuthenticationDetailsSource(authenticationDetailsSource); | |
this.ignoreMatchers.add(new AntPathRequestMatcher(ssoProperties.getLoginPath())); | |
this.ignoreMatchers.add(new AntPathRequestMatcher(ssoProperties.getLogoutPath())); | |
this.ignoreMatchers.addAll(securityProperties.getIgnored().stream().map(AntPathRequestMatcher::new).collect(Collectors.toList())); | |
} | |
@Override | |
public void afterPropertiesSet() { | |
Assert.state(restTemplate != null, "Supply a rest-template"); | |
super.afterPropertiesSet(); | |
} | |
@Override | |
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) { | |
// Do not try to authenticate against any of the ignored matchers | |
for (RequestMatcher m : ignoreMatchers) { | |
if (m.matches(request)) { | |
return null; | |
} | |
} | |
OAuth2AccessToken accessToken = null; | |
try { | |
accessToken = restTemplate.getAccessToken(); | |
} catch (UserRedirectRequiredException e) { | |
log.debug("Not authenticated", e); | |
//throw e; | |
} | |
if (accessToken == null) { | |
return null; | |
} | |
try { | |
OAuth2Authentication result = tokenServices.loadAuthentication(accessToken.getValue()); | |
if (authenticationDetailsSource != null) { | |
request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, accessToken.getValue()); | |
request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE, accessToken.getTokenType()); | |
result.setDetails(authenticationDetailsSource.buildDetails(request)); | |
} | |
return result; | |
} | |
catch (InvalidTokenException ignore) {} | |
return null; | |
} | |
@Override | |
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) { | |
return request.getAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE) != null ? "N/A" : null; | |
} | |
@Override | |
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) { | |
super.successfulAuthentication(request, response, authResult); | |
} | |
@Override | |
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) { | |
} | |
private static class NoopAuthenticationManager implements AuthenticationManager { | |
@Override | |
public Authentication authenticate(Authentication authentication) throws AuthenticationException { | |
return authentication; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment