Skip to content

Instantly share code, notes, and snippets.

@leon
Created May 7, 2015 09:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leon/182f2a221341411f7d1a to your computer and use it in GitHub Desktop.
Save leon/182f2a221341411f7d1a to your computer and use it in GitHub Desktop.
WIP sso pre auth filter
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