Google profile details in Spring Boot application

Google profile details in Spring Boot application In the previous article about Spring Boot integration with Google Sign-In, I configured a simple application with security based on Google Sign-In. Usually, you are interested not only in knowing that a user has logged into but you would like to know who he/she is. Google allows for that. The application can read the user's profile and this is what I am going to show you.

profileIn the previous article about Spring Boot integration with Google Sign-In, I configured a simple application with security based on Google Sign-In. Usually, you are interested not only in knowing that a user has logged into but you would like to know who he/she is. Google allows for that. The application can read the user's profile and this is what I am going to show you. 

I already have the application built based on this article - Getting started with Google Sign-In in spring boot app. To sum up, it consists of two pages: index.html which is available for everyone and restricted.html which is shown to users that are signed in to a Google account.

It is cool if this is all you need to do from the security perspective but real-life applications usually need a little bit more. Let's assume, I need details of the signed in user. A reason could be a need of auditing, checking privileges, sending an email etc.

You probably remember application.yml from my application:

security:
oauth2:
client:
clientId: aaaaaaaabbbbbbbbbbbbcccccccccc.apps.googleusercontent.com
clientSecret: 111122223333334444445555
accessTokenUri: https://www.googleapis.com/oauth2/v3/token
userAuthorizationUri: https://accounts.google.com/o/oauth2/auth
tokenName: oauth_token
authenticationScheme: query
clientAuthenticationScheme: form
scope: profile
resource:
userInfoUri: https://www.googleapis.com/userinfo/v2/me
preferTokenInfo: false

The scope parameter determines what kind of data the application wants to read from the Google account. This data can be read by my application after a user sign-in and consent.

 

Reading Google profile data

I have a REST endpoint that is restricted to authenticated users only and it looks like below:

@RestController
@RequestMapping(value = "/reservations")
public class ReservationsController {

@RequestMapping(value = "/", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@Transactional
public ResponseEntity createReservation(@RequestBody ReservationDTO reservationDTO) {
...
System.out.println(reservationDTO);
return new ResponseEntity(HttpStatus.OK);
}

}

I want to know the user's identity inside the createReservation method so I need to pass an authentication object into the method somehow. It is very easy with Spring Security. The whole authentication process with Google Sign-In is based on OAuth2 algorithm so it is enough to inject an object of the OAuth2Authentication type to the method.

@RestController
@RequestMapping(value = "/reservations")
public class ReservationsController {

@RequestMapping(value = "/", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@Transactional
public ResponseEntity createReservation(@RequestBody ReservationDTO reservationDTO, OAuth2Authentication authentication) throws ParseException {
System.out.println(reservationDTO);
return new ResponseEntity(HttpStatus.OK);
}

}

OAuth2Authentication class implements the Authentication interface and it is general enough to be able to store information for different authentication types. To find out what it actually contains, I have to use a debugger to view its content. This is what I found:

OAuth2Authentication profile

As you can see above, the profile details are stored as a Map under authentication.userAuthentication.details path of nesting. The above screenshot teaches me what are the keys for each piece of data from the profile. They can be extracted by using the following code.

LinkedHashMap<String, String> details = (LinkedHashMap<String, String>)authentication.getUserAuthentication().getDetails();
System.out.println("id=" + details.get("id"));
System.out.println("name=" + details.get("name"));

 

Reading email address

If profile data is not enough, the scope of returned accoung information can be extended by email address. It can be achieved by changing the scope to email.

security:
oauth2:
client:
clientId: aaaaaaaabbbbbbbbbbbbcccccccccc.apps.googleusercontent.com
clientSecret: 111122223333334444445555
accessTokenUri: https://www.googleapis.com/oauth2/v3/token
userAuthorizationUri: https://accounts.google.com/o/oauth2/auth
tokenName: oauth_token
authenticationScheme: query
clientAuthenticationScheme: form
scope: email
resource:
userInfoUri: https://www.googleapis.com/userinfo/v2/me
preferTokenInfo: false

Executing the same steps with this configuration leads to the following information visible in the authentication object.

OAuth2Authentication

 

 

This post shows how simple is reading a Google user's profile. If you have not seen the previous one about integrating a web application with Google Sign-In yet, check it out.