Spring OAuth2 client— integrate with social login
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.
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
- source code at github
Happy Coding!