Spring OAuth2 client— integrate with social login

Rui Zhou
Javarevisited
Published in
4 min readFeb 28, 2024
GuangZhou, PRC
Photo by Vincent Chan on Unsplash

In this article, I will give an example of how to use Spring OAuth2 client to integrate with social login with just a few lines of kotlin code and configuration.

See the below diagram, Google/Facebook account service is the Authorization Server. When they receive Auth Code request from a client application, they will redirect them to login page, end user will complete the social login on the page and will be redirected back to the original login page.

https://www.baeldung.com/spring-security-oauth-resource-server

Setup Google OAuth2 Client

First of all, goto https://console.cloud.google.com/apis/dashboard?pli=1, we need to create new project, e.g. spring-oauth2-client

then we add Credentials and OAuth consent screen

Remember that We also have to configure an authorized redirect URI in the Google Console, which is the path that users will be redirected to after they successfully log in with Google.

By default, Spring Boot configures this redirect URI as /login/oauth2/code/{registrationId}.

So, for Google we’ll add this URI:

http://localhost:8081/login/oauth2/code/google

Spring Boot Configuration

dependency in build.gradle

implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")

See org/springframework/security/config/oauth2/client/CommonOAuth2Provider.java, Spring-boot-starter-oauth2-client has built-in support for OAuth2 client Google, Github, Facebook and Okta.

public enum CommonOAuth2Provider {

GOOGLE {

@Override
public Builder getBuilder(String registrationId) {
ClientRegistration.Builder builder = getBuilder(registrationId,
ClientAuthenticationMethod.CLIENT_SECRET_BASIC, DEFAULT_REDIRECT_URL);
builder.scope("openid", "profile", "email");
builder.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth");
builder.tokenUri("https://www.googleapis.com/oauth2/v4/token");
builder.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs");
builder.issuerUri("https://accounts.google.com");
builder.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo");
builder.userNameAttributeName(IdTokenClaimNames.SUB);
builder.clientName("Google");
return builder;
}

}
// xxxx

application.yaml

spring:
security:
oauth2:
client:
registration:
google:
client-id: your_client_id
client-secret: your_client_secret

mykeycloak:
client-id: login-app
authorization-grant-type: authorization_code
scope: openid
provider:
mykeycloak:
issuer-uri: http://localhost:8080/auth/realms/SpringBootKeycloak
user-name-attribute: preferred_username

Add the above configurations under oauth2.client.registration in spring boot profile will enable the Oauth2ClientAutoConfiguration and create the necessary beans. We can also add Facebook or our customized client mykeycloak

to setup keycloak authorization server, refer to this https://medium.com/@wirelesser/oauth2-write-a-resource-server-with-keycloak-and-spring-security-c447bbca363c

Testing

Spring OAuth2 client will automatically set /login as the default login page, all other requests need to be authenticated.

Start the application at 8081 port, and input http://localhost:8081/ in the browser, it will be routed to the default login page because it is not authenticated yet.

=>

after login successfully it will be routed to the default home page /

logout is

Start independently

Note: It must start keycloak server first because spring boot oauth2 client will try to fetch oauth2 client configuration information from keycloak server.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientRegistrationRepository' defined in class path resource [org/springframework/boot/autoconfigure/security/oauth2/client/servlet/OAuth2ClientRegistrationRepositoryConfiguration.class]: Failed to instantiate [org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository]: Factory method 'clientRegistrationRepository' threw exception with message: Unable to resolve Configuration with the provided Issuer of "http://localhost:8080/auth/realms/SpringBootKeycloak"

If we need to start it independently, then we can supply the jwk-set-uri property instead to point to the authorization server’s endpoint exposing public keys:

spring:
security:
oauth2:
client:
registration:
google:
client-id: 1043125932604-sq96atrmiserm85fds8apsimbpgg40dv.apps.googleusercontent.com
client-secret: your_google_secret

facebook:
client-id: your_facebook_id
client-secret: your_facebook_secret

mykeycloak:
client-id: login-app
authorization-grant-type: authorization_code
scope: openid
redirectUri: http://localhost:8081/login/oauth2/code/mykeycloak

provider:
mykeycloak:
user-name-attribute: preferred_username
jwk-set-uri: http://localhost:8080/auth/realms/SpringBootKeycloak/protocol/openid-connect/certs
authorization-uri: http://localhost:8080/auth/realms/SpringBootKeycloak/protocol/openid-connect/auth
token-uri: http://localhost:8080/auth/realms/SpringBootKeycloak/protocol/openid-connect/token
user-info-uri: http://localhost:8080/auth/realms/SpringBootKeycloak/protocol/openid-connect/userinfo

Reference

Happy Coding!

--

--