Blog

OAuth 2 and Google Sign-in for a Vaadin Application

By  
Tarek Oraby
Tarek Oraby
·
On Mar 30, 2022 3:39:41 PM
·

login screen on a purple background

In this guide, we learn how to provide users with the ability to sign in to a Vaadin application using their Google account. This is a lightweight alternative to integrating a fully-fledged identity management server or SSO Kit into your stack. Using OAuth 2 in this manner already enhances security and simplifies the sign-in process for end users by eliminating the need to create application-specific credentials. Taking advantage of Vaadin Spring Security helpers, we’ll see how easy it is to create a minimal application that uses Google for authentication.

You can explore the full source code of this guide on GitHub. For plain Java projects, you can check this example implementation of Google OAuth 2-based login.

Google sign in screen on a purple background

What you need

  • About 15 minutes
  • JDK 17 or later
  • A Gmail email address

Step 1: Create Google OAuth 2.0 Client ID

To create a client ID, you will first need to create a Google Cloud project, and add an OAuth consent screen to that project. To do this, go to the OAuth consent screen at Google Cloud Platform. There you can create a new project and create its OAuth consent screen (select “External” when prompted for the “User Type” of the consent screen).

Once the project with a consent screen is created, go to the credentials page and do the following:

  1. Select “Create credentials”, followed by “OAuth client ID”. 
  2. When prompted for the application type, select “Web application”.
  3. In the “Authorized redirect URIs” field, add a new redirect for http://localhost:8080/login/oauth2/code/google.

Once the OAuth client is created, take a note of the generated client ID and client secret.

Step 2: Import a Started Project

Click here to download an empty project starter. Unpack the downloaded zip into a folder on your computer, and import the project in the IDE of your choice.

Step 3: Add Spring Security OAuth 2.0 Client

Add the following dependency to the pom.xml file:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

Then, to make the link to Google, add the following to your application.properties file (replacing the client ID and secret with the actual values that you obtained from the credentials page of the Google Cloud project):

Spring.security.oauth2.client.registration.google.client-id= 
<your client id>
spring.security.oauth2.client.registration.google.client-secret=
<your client secret>

Alternatively, or maybe even preferably, you might want to provide these values for example as environment variables via Spring Boot's externalied configuration.

Step 4: Add SecurityConfiguration Class

Next we configure Spring Security using the VaadinWebSecurity helper. VaadinWebSecurity provides basic Vaadin security configuration for the project out of the box. It sets up security rules for a Vaadin application and restricts all URLs to authenticated users, except for public resources and internal Vaadin URLs.

Add the following SecurityConfiguration class to your application. Note that in this class, we only need to alter the HttpSecurity configuration in order to add authentication support using OAuth 2.0. Other security configurations will be handled automatically by VaadinWebSecurity.

import com.vaadin.flow.spring.security.VaadinWebSecurity;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends VaadinWebSecurity {
   
   private static final String LOGIN_URL = "/login";
   
   @Override
   protected void configure(HttpSecurity http) throws Exception {
       super.configure(http);
       http.oauth2Login().loginPage(LOGIN_URL).permitAll();
   }
}

Step 5: Add Login View

After completing the previous step, any unauthenticated attempt to access a URL in the application will be redirected to the /login path. Now we need to create the actual login view. 

Add the following LoginView class, which is a standard Vaadin view with a link connecting to Google login services. Note that this view is annotated with @AnonymousAllowed in order to make the view publicly accessible for non-authenticated users.

import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.auth.AnonymousAllowed;

@Route("login")
@PageTitle("Login")
@AnonymousAllowed
public class LoginView extends VerticalLayout {
    // URL that Spring Security uses to connect to Google services
    private static final String OAUTH_URL = "/oauth2/authorization/google";

    public LoginView() {
        Anchor loginLink = new Anchor(OAUTH_URL, "Login with Google");
        // Instruct Vaadin Router to ignore doing SPA handling
        loginLink.setRouterIgnore(true);
        add(loginLink);
    }
}
 

Step 6: Add a Secure View

To verify that the sign-in mechanism is working as intended, let us now add a view that would be accessible to authenticated users only. The following MainView is annotated with @PermitAll to allow authenticated users to navigate to this view. The view also contains a logout button that users can use to explicitly log out. Note also that the view renders the user’s first name, last name, email, and picture as they appear in their Google account, using the OAuth2AuthenticatedPrincipal object. 

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Image;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.VaadinServletRequest;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import jakarta.annotation.security.PermitAll;

@Route("")
@PermitAll
public class MainView extends VerticalLayout {

   private static final String LOGOUT_SUCCESS_URL = "/";

   public MainView() {
       // Using the raw Spring Security API directly do access Google provided
       // credentials and doing logout. Check the GitHub example for a better basis
       // an actual application, where these details are refactored to a separate UserSession bean
       Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
       OAuth2AuthenticatedPrincipal principal = (OAuth2AuthenticatedPrincipal) authentication.getPrincipal();

       String givenName = principal.getAttribute("given_name");
       String familyName = principal.getAttribute("family_name");
       String email = principal.getAttribute("email");
       String picture = principal.getAttribute("picture");

       H2 header = new H2("Hello " + givenName + " " + familyName + " (" + email + ")");
       Image image = new Image(picture, "User Image");

       Button logoutButton = new Button("Logout", click -> {
           UI.getCurrent().getPage().setLocation(LOGOUT_SUCCESS_URL);
           SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler();
           logoutHandler.logout(
                   VaadinServletRequest.getCurrent().getHttpServletRequest(), null,
                   null);
       });

       setAlignItems(Alignment.CENTER);
       add(header, image, logoutButton);
   }
}

Step 7: Run the Application

To test the application, run the main method of the Application class. Alternatively, to run the project from the command line, type mvnw spring-boot:run (on Windows), or ./mvnw spring-boot:run (on macOS or Linux).

Then, in your browser, open http://localhost:8080/.

Go further

We have seen how to use Vaadin security helpers and Spring Security to build an application with Google sign-in. The approach described here can also be used to enable authentication using other OAuth 2.0 providers, such as GitHub for example. You can learn more about configuring security using Vaadin helpers in the documentation.

You can explore the full source code of this guide on GitHub.

Tarek Oraby
Tarek Oraby
Tarek is a Product Manager at Vaadin. His daily work is a blend of talking to users, planning, and overseeing the evolution of Vaadin Flow and Hilla, ensuring they consistently delight our developer community.
Other posts by Tarek Oraby