Google Login with oauth2Login

Register the App at Google

  1. Open Google Cloud Console → APIs & Services → OAuth consent screen. Choose "External", fill the app name (ShopEase) and support email.
  2. Go to Credentials → Create credentials → OAuth client ID, type Web application.
  3. Add the authorized redirect URI http://localhost:8080/login/oauth2/code/google (and later https://shopease.in/login/oauth2/code/google).
  4. Copy the Client ID and Client secret into environment variables — never into Git.

Dependency and Configuration

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

application.yml

Spring Boot already knows Google's endpoints (it is a built-in "common provider"), so you only add the credentials:

src/main/resources/application.yml

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: ${GOOGLE_CLIENT_ID}
            client-secret: ${GOOGLE_CLIENT_SECRET}
            scope: openid, profile, email
          github:
            client-id: ${GITHUB_CLIENT_ID}
            client-secret: ${GITHUB_CLIENT_SECRET}

Security Configuration

package in.shopease.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final ShopEaseOidcUserService oidcUserService;

    public SecurityConfig(ShopEaseOidcUserService oidcUserService) {
        this.oidcUserService = oidcUserService;
    }

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/", "/products/**", "/login", "/error", "/css/**").permitAll()
                .anyRequest().authenticated())
            .oauth2Login(oauth -> oauth
                .loginPage("/login")                                   // your own page with the buttons
                .userInfoEndpoint(userInfo -> userInfo.oidcUserService(oidcUserService))
                .defaultSuccessUrl("/account", true))
            .logout(logout -> logout.logoutSuccessUrl("/"));
        return http.build();
    }
}

Your login page just links to /oauth2/authorization/google. Spring Security builds the authorize URL (with state, nonce and PKCE), handles the callback at /login/oauth2/code/google, exchanges the code, validates the ID token and creates the session.

<a href="/oauth2/authorization/google">Continue with Google</a>
<a href="/oauth2/authorization/github">Continue with GitHub</a>

Reading the Logged-in User

@RestController
public class AccountController {

    @GetMapping("/api/me")
    public Map<String, Object> me(@AuthenticationPrincipal OidcUser user) {
        return Map.of(
            "name", user.getFullName(),
            "email", user.getEmail(),
            "provider", "google",
            "roles", user.getAuthorities().stream().map(GrantedAuthority::getAuthority).sorted().toList());
    }
}

Request

After logging in with Google in the browser, the session cookie identifies the user:

curl -s http://localhost:8080/api/me -H "Cookie: JSESSIONID=8C2F1D5E0A6B4F1F9D3A7B2C1E0F9A8B"

Example output

{
  "name": "Asha Verma",
  "email": "[email protected]",
  "provider": "google",
  "roles": ["OIDC_USER", "ROLE_CUSTOMER", "SCOPE_email", "SCOPE_openid", "SCOPE_profile"]
}

Linking Google Users to ShopEase Users

Google tells you who the user is; ShopEase still decides what they may do. Extend OidcUserService to create a local User on first login and add your own roles:

@Service
public class ShopEaseOidcUserService extends OidcUserService {

    private final UserRepository users;

    public ShopEaseOidcUserService(UserRepository users) {
        this.users = users;
    }

    @Override
    @Transactional
    public OidcUser loadUser(OidcUserRequest request) throws OAuth2AuthenticationException {
        OidcUser oidcUser = super.loadUser(request);           // validates and reads the ID token
        String provider = request.getClientRegistration().getRegistrationId();   // "google"

        if (!Boolean.TRUE.equals(oidcUser.getEmailVerified())) {
            throw new OAuth2AuthenticationException(new OAuth2Error("email_not_verified"),
                    "Your Google email is not verified");
        }

        User user = users.findByProviderAndProviderId(provider, oidcUser.getSubject())
                .orElseGet(() -> users.save(User.fromOidc(provider, oidcUser.getSubject(),
                        oidcUser.getEmail(), oidcUser.getFullName())));

        Set<GrantedAuthority> authorities = new HashSet<>(oidcUser.getAuthorities());
        user.getRoles().forEach(role -> authorities.add(new SimpleGrantedAuthority("ROLE_" + role)));

        // "email" becomes the value of authentication.getName()
        return new DefaultOidcUser(authorities, oidcUser.getIdToken(), oidcUser.getUserInfo(), "email");
    }
}

Tip: GitHub is plain OAuth2, not OIDC. For it, extend DefaultOAuth2UserService and register it with userInfo.userService(...).