Spring OAuth2 Notes
Spring OAuth2 101
@EnableOAuth2Sso annotation
- OAuth2 client VS Authentication
- @EnableOAuth2Clientis lower level
- The client is re-usable, talks to OAuth2 resources that Authorization Server provides
WebSecurityConfigurerAdapter
- WebSecurityConfigurer+- @EnableOAuth2Ssoclass: configure the security filter chain that carries the OAuth2 authentication processor.
- Home page and login page should be visible in authorizeRequests().
- Others require authentication, e.g., /user.
- /logoutrequires POST. Protect user from Cross Site Request Forgery (CSRF).
- Requires a token in the request to link to the current session.
Principal
@SpringBootApplication
@EnableOAuth2Sso
@RestController
public class SocialApplication extends WebSecurityConfigurerAdapter {
    @RequestMapping("/user")
    public Principal user(Principal principal) {
        return principal;
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/**")
            .authorizeRequests()
             .antMatchers("/", "/login**", "/webjars/**", "/error**")
             .permitAll()
            .anyRequest()
             .authenticated()
            .and()
             .logout()
             .logoutSuccessUrl("/")
             .permitAll()
             .and()
             .csrf()
             .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
    }
    public static void main(String[] args) {
        SpringApplication.run(SocialApplication.class, args);
    }
}
- All requests are protected by default
- The home page and login endpoints are explicitly excluded
- All other endpoints require an authenticated user
- Unauthenticated users are re-directed to the home page
OAuth2ClientContext
Build an authentication filter that we add to our security configuration.
- @Autowired OAuth2ClientContext
- Add your own filter method
- Chain your filter in the configure
- Declar your client registration
- Reource endpoint
@Autowired
OAuth2ClientContext oauth2ClientContext;
@Override
protected void configure(HttpSecurity http) throws Exception {
  http.antMatcher("/**")
    ...
    .and().addFilterBefore(mySsoFilter(), BasicAuthenticationFilter.class);
}
private Filter mySsoFilter() {
  OAuth2ClientAuthenticationProcessingFilter facebookFilter = new OAuth2ClientAuthenticationProcessingFilter("/login/facebook");
  OAuth2RestTemplate facebookTemplate = new OAuth2RestTemplate(facebook(), oauth2ClientContext);
  facebookFilter.setRestTemplate(facebookTemplate);
  UserInfoTokenServices tokenServices = new UserInfoTokenServices(facebookResource().getUserInfoUri(), facebook().getClientId());
  tokenServices.setRestTemplate(facebookTemplate);
  facebookFilter.setTokenServices(tokenServices);
  return facebookFilter;
}
@Bean
@ConfigurationProperties("facebook.client")
public AuthorizationCodeResourceDetails facebook() {
 return new AuthorizationCodeResourceDetails();
}
@Bean
@ConfigurationProperties("facebook.resource")
public ResourceServerProperties facebookResource() {
 return new ResourceServerProperties();
}
Add another authentication server, like Github
- Use CompositeFilter
- Add new beans
private Filter ssoFilter() {
  CompositeFilter filter = new CompositeFilter();
  List<Filter> filters = new ArrayList<>();
  filters.add(ssoFilter(facebook(), "/login/facebook"));
  filters.add(ssoFilter(github(), "/login/github"));
  filter.setFilters(filters);
  return filter;
}
private Filter ssoFilter(ClientResources client, String path) {
  OAuth2ClientAuthenticationProcessingFilter filter = new OAuth2ClientAuthenticationProcessingFilter(path);
  OAuth2RestTemplate template = new OAuth2RestTemplate(client.getClient(), oauth2ClientContext);
  filter.setRestTemplate(template);
  UserInfoTokenServices tokenServices = new UserInfoTokenServices(
      client.getResource().getUserInfoUri(), client.getClient().getClientId());
  tokenServices.setRestTemplate(template);
  filter.setTokenServices(tokenServices);
  return filter;
}
@Bean
@ConfigurationProperties("github.client")
public AuthorizationCodeResourceDetails github() {
 return new AuthorizationCodeResourceDetails();
}
@Bean
@ConfigurationProperties("github.resource")
public ResourceServerProperties githubResource() {
 return new ResourceServerProperties();
}
Handling Redirects
- Register the existing register in a low order, makes sure it comes before the main Spring Security filter.
@Bean
public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
 FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<>();
 registration.setFilter(filter);
 registration.setOrder(-100);
 return registration;
}
@EnableAuthorizationServer
Authorization Server is a bunch of endpoints. comming soon…
