Spring OAuth2 Notes
Spring OAuth2 101
@EnableOAuth2Sso annotation
- OAuth2 client VS Authentication
@EnableOAuth2Client
is lower level- The client is re-usable, talks to OAuth2 resources that Authorization Server provides
WebSecurityConfigurerAdapter
WebSecurityConfigurer
+@EnableOAuth2Sso
class: 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
. /logout
requires 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…