4. Single Sign On

You can use an OAuth2 Client to fetch user details from the provider (if such features are available) and then convert them into an Authentication token for Spring Security. The Resource Server (described earlier) supports this through the user-info-uri property. This is the basis for a Single Sign On (SSO) protocol based on OAuth2, and Spring Boot makes it easy to participate by providing an annotation @EnableOAuth2Sso. The Github client shown in the preceding section can protect all its resources and authenticate by using the Github /user/ endpoint, by adding that annotation and declaring where to find the endpoint (in addition to the security.oauth2.client.* configuration already listed earlier):

Example 4.1. application.yml

security:
  oauth2:
# ...
  resource:
    userInfoUri: https://api.github.com/user
    preferTokenInfo: false

Since all paths are secure by default, there is no “home” page that you can show to unauthenticated users and invite them to login (by visiting the /login path, or the path specified by security.oauth2.sso.login-path).

To customize the access rules or paths to protect s(o you can add a “home” page for instance,) you can add @EnableOAuth2Sso to a WebSecurityConfigurerAdapter. The annotation causes it to be decorated and enhanced with the necessary pieces to get the /login path working. In the following example, we simply allow unauthenticated access to the home page at / and keep the default for everything else:

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .mvcMatchers("/").permitAll()
                .anyRequest().authenticated();
    }
}

Also, note that, since all endpoints are secure by default, this includes any default error handling endpoints — for example, the /error endpoint. This means that, if there is some problem during Single Sign On that requires the application to redirect to the /error page, this can cause an infinite redirect between the identity provider and the receiving application.

First, think carefully about making an endpoint insecure, as you may find that the behavior is simply evidence of a different problem. However, this behavior can be addressed by configuring the application to permit /error, as the following example shows:

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/error").permitAll()
                .anyRequest().authenticated();
    }
}