Created
August 24, 2014 06:45
-
-
Save yterradas/0fe2ab41081e9a676f3e to your computer and use it in GitHub Desktop.
Custom filter added to spring security filter chain.
This file contains hidden or 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
| @Configuration | |
| @EnableWebMvcSecurity | |
| public class WebSecurityConfig | |
| extends WebSecurityConfigurerAdapter { | |
| @Value("${oauth.check_token.url:http://localhost:3030/oauth/token/info}") | |
| private String checkTokenUrl; | |
| @Autowired @Qualifier("restTemplate") | |
| private RestOperations authRestTemplate; | |
| @Override | |
| protected void configure( HttpSecurity http ) | |
| throws Exception { | |
| // @formatter:off | |
| http.addFilterAfter(customAuthFilter(), SessionManagementFilter.class) | |
| .anonymous().disable() | |
| .httpBasic().disable() | |
| .formLogin().disable() | |
| .x509().disable() | |
| .jee().disable() | |
| .csrf().disable() | |
| .logout().disable() | |
| .rememberMe().disable(); | |
| // @formatter:on | |
| } | |
| @Override | |
| public void configure( WebSecurity web ) | |
| throws Exception { | |
| // @formatter:off | |
| // NOTE: disable in production | |
| web.debug(true); | |
| // @formatter:on | |
| } | |
| private ProxyAuthenticationFilter customAuthFilter() | |
| throws Exception { | |
| return new ProxyAuthenticationFilter(checkTokenUrl, authRestTemplate); | |
| } | |
| } | |
| public class ProxyAuthenticationFilter | |
| extends AbstractAuthenticationProcessingFilter { | |
| private final Logger log = LoggerFactory.getLogger(getClass()); | |
| private RestOperations authTemplate; | |
| private String checkTokenUrl; | |
| public ProxyAuthenticationFilter( final String checkTokenUrl, final RestOperations authTemplate ) { | |
| super(new AntPathRequestMatcher("/**")); | |
| this.checkTokenUrl = checkTokenUrl; | |
| this.authTemplate = authTemplate; | |
| } | |
| @Override | |
| public Authentication attemptAuthentication( HttpServletRequest request, HttpServletResponse response ) | |
| throws AuthenticationException { | |
| AuthUserInfo userInfo = getUserInfo(request); | |
| // NOTE: delete when provider provide details | |
| if ( null != userInfo ) { | |
| userInfo.setUserId("abcde12345"); | |
| userInfo.setUsername("username"); | |
| } | |
| if ( null == userInfo ) { | |
| throw new AuthenticationCredentialsNotFoundException("Could not createAuthentication user"); | |
| } | |
| if ( isEmpty(userInfo.getUsername()) || isEmpty(userInfo.getUserId()) ) { | |
| throw new BadCredentialsException("User details does not have sufficient credentials"); | |
| } | |
| // NOTE: delete when provider provide roles | |
| List<? extends GrantedAuthority> authorities = Collections | |
| .unmodifiableList(Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"))); | |
| AuthUser principal = new AuthUser(userInfo.getUsername(), userInfo.getUserId(), authorities); | |
| // NOTE: set credentials when provider provides them | |
| UsernamePasswordAuthenticationToken authResult = | |
| new UsernamePasswordAuthenticationToken(principal, null, authorities); | |
| authResult.setDetails(authenticationDetailsSource.buildDetails(request)); | |
| return authResult; | |
| } | |
| @Override | |
| protected void successfulAuthentication( HttpServletRequest request, | |
| HttpServletResponse response, | |
| FilterChain chain, | |
| Authentication authResult ) | |
| throws IOException, ServletException { | |
| if ( logger.isDebugEnabled() ) { | |
| logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult); | |
| } | |
| SecurityContextHolder.getContext().setAuthentication(authResult); | |
| if ( this.eventPublisher != null ) { | |
| eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass())); | |
| } | |
| chain.doFilter(request, response); | |
| } | |
| private AuthUserInfo getUserInfo( final HttpServletRequest req ) { | |
| final String bearer = req.getHeader("Authorization"); | |
| Validate.notEmpty(bearer, "Authorization Bearer must be present"); | |
| if ( log.isDebugEnabled() ) { | |
| log.debug("Attempting to createAuthentication: {}", bearer); | |
| } | |
| final HttpEntity<String> entity = new HttpEntity<>( | |
| new HttpHeaders() {{ | |
| set("Authorization", bearer); | |
| }} | |
| ); | |
| AuthUserInfo userInfo = null; | |
| try { | |
| ResponseEntity<AuthUserInfo> authProviderResponse = authTemplate | |
| .exchange(checkTokenUrl, HttpMethod.GET, entity, AuthUserInfo.class); | |
| userInfo = authProviderResponse.getBody(); | |
| } catch (RestClientException e) { | |
| log.error("Failure communicating with OAuth provider", e); | |
| } | |
| return userInfo; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment