Spring Boot OAuth2 Login
January 24, 2020
This page will walk through Spring Boot 2.x OAuth2 login example. Spring Boot 2.x provides full auto-configuration for OAuth2 login. We just need to configure client id and client secret for OAuth2 provider such as GitHub, Facebook and Google in application property file and we are done. We can customize the configuration by overriding methods of WebSecurityConfigurerAdapter
and using HttpSecurity.oauth2Login()
method introduced in Spring 5.0. We need to create a bean for ClientRegistrationRepository
to override OAuth2 property value.
Here on this page we will create a Spring Boot Security application for OAuth2 login using GitHub, Facebook and Google authentication provider.
Contents
Maven Dependencies
Find the Maven dependencies.pom.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.5.RELEASE</version> <relativePath /> </parent> <properties> <context.path>spring-app</context.path> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-client</artifactId> <version>5.1.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-jose</artifactId> <version>5.1.7.RELEASE</version> </dependency> </dependencies>
Spring Boot 2.x OAuth2 Client Properties
To enable OAuth2 login using Spring Boot 2.x auto-configuration, just configure minimum two properties given below and we are done.spring.security.oauth2.client.registration.[registrationId].client-id
spring.security.oauth2.client.registration.[registrationId].client-secret
The registrationId is
google
, github
, facebook
etc. To configure all these OAuth2 provider, find the property file.
application.properties
spring.security.oauth2.client.registration.github.client-id= github-client-id spring.security.oauth2.client.registration.github.client-secret= github-client-secret spring.security.oauth2.client.registration.facebook.client-id= facebook-client-id spring.security.oauth2.client.registration.facebook.client-secret= facebook-client-secret spring.security.oauth2.client.registration.google.client-id= google-client-id spring.security.oauth2.client.registration.google.client-secret= google-client-secret
application.yml
spring: security: oauth2: client: registration: github: client-id: github-client-id client-secret: github-client-secret facebook: client-id: facebook-client-id client-secret: facebook-client-secret google: client-id: google-client-id client-secret: google-client-secret
Using Spring HttpSecurity.oauth2Login()
The HttpSecurity.oauth2Login()
method has been introduced in Spring 5.0. The oauth2Login()
method configures authentication support using an OAuth 2.0 or OpenID Connect 1.0 Provider. The default configuration will auto-generate a login page at /login
URL. Find the code using oauth2Login()
method.
SecurityConfig.java
package com.concretepage; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/", "/login**", "/error**").permitAll() .anyRequest().authenticated() .and().logout().logoutUrl("/logout").logoutSuccessUrl("/") .and().oauth2Login(); } }
Overriding OAuth2 Auto-Configuration
To override Spring Boot auto-configuration for OAuth2 login, we need to create a bean forClientRegistrationRepository
which is instantiated by passing the list of ClientRegistration
instances. The ClientRegistration
is the representation of a client registration with an OAuth 2.0 or OpenID Connect 1.0 Provider. Find the sample code to override auto-configuration for OAuth2 login with GitHub and Google.
SecurityConfig.java
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/", "/login**", "/error**").permitAll() .anyRequest().authenticated() .and().logout().logoutUrl("/logout").logoutSuccessUrl("/") .and().oauth2Login(); } @Bean public ClientRegistrationRepository clientRegistrationRepository() { List<ClientRegistration> registrations = new ArrayList<>(); registrations.add(githubClientRegistration()); registrations.add(googleClientRegistration()); return new InMemoryClientRegistrationRepository(registrations); } private ClientRegistration githubClientRegistration() { return ClientRegistration.withRegistrationId("github") .clientId("github-client-id") .clientSecret("github-client-secret") .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}") .authorizationUri("https://github.com/login/oauth/authorize") .tokenUri("https://github.com/login/oauth/access_token") .userInfoUri("https://api.github.com/user") .clientName("GitHub").build(); } private ClientRegistration googleClientRegistration() { return ClientRegistration.withRegistrationId("google") .clientId("google-client-id") .clientSecret("google-client-secret") .clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE) .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}") .scope("openid", "profile", "email", "address", "phone") .authorizationUri("https://accounts.google.com/o/oauth2/v2/auth") .tokenUri("https://www.googleapis.com/oauth2/v4/token") .userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo") .userNameAttributeName(IdTokenClaimNames.SUB) .jwkSetUri("https://www.googleapis.com/oauth2/v3/certs") .clientName("Google").build(); } }
Create Controller and View
AppController.javapackage com.concretepage; import java.security.Principal; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class AppController { @GetMapping("hello") public ModelAndView welcome(Principal principal) { ModelAndView mav = new ModelAndView(); mav.setViewName("welcome"); mav.addObject("name", principal.getName()); return mav; } }
<!doctype html> <html> <head> <title>Spring Security</title> </head> <body> <h3> <a href="/oauth2/authorization/github" th:href="@{/hello}" th:if="${#httpServletRequest?.remoteUser != undefined }"> Go to Dashboard </a> <a href="/hello" th:href="@{/oauth2/authorization/github}" th:if="${#httpServletRequest?.remoteUser == undefined }"> Login with GitHub </a> <br/><br/> <a href="/hello" th:href="@{/oauth2/authorization/facebook}" th:if="${#httpServletRequest?.remoteUser == undefined }"> Login with Facebook </a> <br/><br/> <a href="/hello" th:href="@{/oauth2/authorization/google}" th:if="${#httpServletRequest?.remoteUser == undefined }"> Login with Google </a> </h3> </body> </html>
<!doctype html> <html lang="en"> <head> <title>Welcome</title> </head> <body> Welcome <b th:inline="text"> [[${name}]] </b> <br/><br/> <form th:action="@{/logout}" method="POST"> <input type="submit" value="Logout"/> </form> </body> </html>
<!doctype html> <html> <head> <title>Spring Security</title> </head> <body> An error occurred. </body> </html>
package com.concretepage; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Main { public static void main(String[] args) { SpringApplication.run(Main.class, args); } }
Output
Download the project and enterclient-id
and client-secret
for google
, github
, facebook
in application.properties
file.
Then run the following command from root folder of the project using command prompt.
mvn spring-boot:run
http://localhost:8080/
References
OAuth 2.0 LoginSpring Doc: HttpSecurity