dcsimg
www.webdeveloper.com
Results 1 to 5 of 5

Thread: Java rest client-server web app - google signin

  1. #1
    Join Date
    Mar 2017
    Posts
    4

    Unhappy Java rest client-server web app - google signin

    (Admins : i am posting this again because my previous thread wasn't quite right. Feel free to remove the old one, but pls keep this one)

    Hello.

    I am a Java Developer and i am trying to add google signin to my restful client-server app.

    I have followed the instructions here precisely :
    https://developers.google.com/identi...onsole-project

    But it isn't working. Here is my code :

    ...
    private static final HttpTransport transport = new NetHttpTransport();
    private static final JacksonFactory jsonFactory = new JacksonFactory();
    ...
    public UsernamePasswordAuthenticationToken verify(final String idTokenString){

    GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
    .setAudience(Arrays.asList(
    "wouldntyouliketoknow",
    "youdidntsaythemagicword"))
    .setIssuer("accounts.google.com")
    .build();

    try {
    System.out.println("\n\t"+idTokenString+"\n\n");

    GoogleIdToken idToken = verifier.verify(idTokenString.trim());// <-- THIS RETURNS null WHEN verify FAILS

    if (idToken != null) {
    Payload payload = idToken.getPayload();

    String email = payload.getEmail();

    if(Boolean.valueOf(payload.getEmailVerified())){
    UserJPA jpa = userRepository.findByEmail(email);
    if(jpa==null){
    throw new UsernameNotFoundException("No user found with email = "+email);
    }
    if(!jpa.isRegisterredWithGoogle()){
    throw new UsernameNotFoundException("You did not use the GoogleRegister option during your registration");
    }
    bokiAuthenticationProvider.checkUserActiveAndUnlocked(jpa);

    return new UsernamePasswordAuthenticationToken(jpa.getUsername(), jpa.getPasswordHesh(),
    bokiAuthenticationProvider.getAuthorities(jpa.getUserHasRoleSecurityList()));
    }
    }else{
    // THIS ALWAYS HAPPENS :
    System.out.println("\n\tThe evil gremlin strikes again - Google idToken object is null !!!");
    }
    } catch (GeneralSecurityException | IOException e) {
    e.printStackTrace();
    }

    throw new UsernameNotFoundException("Google token is invalid or expired");
    }

    The problem is that when i try to validate the token, my java validator object keeps returning null.

    I have also checked the tokens i get. Each time i get a different token, and when i put them through the google's online tool :

    https://www.googleapis.com/oauth2/v1...d_token=XYZ123

    they are valid. But my java object validator says they aren't.

    Funny thing is that when the front end (web and android) send their requests, they're not working, but when i take the tokens they used and try them via postman or fiddler, the same requests work fine. We have checked, and all of our codes are accurate.
    Yesterday, our web developer took one of the tokens which didn't work, hard-coded it in his code and tried google signin again, and it worked perfectly. (he later reverted the changes)
    To add to the confusion, now the whole thing started working on and off. The web developer managed to google-singin twice today and it stopped working after that. Nether of us touched anything.

    I have been fighting this gremlin for the past five days now. Please help.

    Best regards,
    Lazaruss

  2. #2
    Join Date
    Mar 2017
    Posts
    4
    Ok. does anyone know where i can contact the guys who developped the google signin ? Is there some complaints form/blog/email i can turn to ?

  3. #3
    Join Date
    Mar 2017
    Posts
    4
    [SOLUTION : ]

    Ok. Since no one knew how to help me, i dropped the designated google libraries and went and made my own token verification from scratch.

    I went and used the google-token-verifier-url-tool here : https://www.googleapis.com/oauth2/v3...d_token=XYZ123

    At the bottom of the page here https://developers.google.com/identi.../OpenIDConnect , i found how to decipher the json.

    What i do i, I contact their online tool in code, get the json response and verify it manually.
    This is my code :

    private Map<String,String> getMapFromGoogleTokenString(final String idTokenString){
    BufferedReader in = null;
    try {
    // get information from token by contacting the google_token_verify_tool url :
    in = new BufferedReader(new InputStreamReader(
    ((HttpURLConnection) (new URL("https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=" + idTokenString.trim()))
    .openConnection()).getInputStream(), Charset.forName("UTF-8")));

    // read information into a string buffer :
    StringBuffer b = new StringBuffer();
    String inputLine;
    while ((inputLine = in.readLine()) != null){
    b.append(inputLine + "\n");
    }

    // transforming json string into Map<String,String> :
    ObjectMapper objectMapper = new ObjectMapper();
    return objectMapper.readValue(b.toString(), objectMapper.getTypeFactory().constructMapType(Map.class, String.class, String.class));

    // exception handling :
    } catch (MalformedURLException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    } catch(Exception e){
    System.out.println("\n\n\tFailed to transform json to string\n");
    e.printStackTrace();
    } finally{
    if(in!=null){
    try {
    in.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    return null;
    }

    // chack the "email_verified" and "email" values in token payload
    private boolean verifyEmail(final Map<String,String> tokenPayload){
    if(tokenPayload.get("email_verified")!=null && tokenPayload.get("email")!=null){
    try{
    return Boolean.valueOf(tokenPayload.get("email_verified")) && tokenPayload.get("email").contains("@gmail.");
    }catch(Exception e){
    System.out.println("\n\n\tCheck emailVerified failed - cannot parse "+tokenPayload.get("email_verified")+" to boolean\n");
    }
    }else{
    System.out.println("\n\n\tCheck emailVerified failed - required information in the token");
    }
    return false;
    }

    // check token expiration is after now :
    private boolean checkExpirationTime(final Map<String,String> tokenPayload){
    try{
    if(tokenPayload.get("exp")!=null){
    // the "exp" value is in seconds and Date().getTime is in mili seconds
    return Long.parseLong(tokenPayload.get("exp")+"000") > new java.util.Date().getTime();
    }else{
    System.out.println("\n\n\tCheck expiration failed - required information in the token\n");
    }
    }catch(Exception e){
    System.out.println("\n\n\tCheck expiration failed - cannot parse "+tokenPayload.get("exp")+" into long\n");
    }
    return false;
    }

    // check that at least one CLIENT_ID matches with token values
    private boolean checkAudience(final Map<String,String> tokenPayload){
    if(tokenPayload.get("aud")!=null && tokenPayload.get("azp")!=null){
    List<String> pom = Arrays.asList("MY_CLIENT_ID_1",
    "MY_CLIENT_ID_2",
    "MY_CLIENT_ID_3");

    if(pom.contains(tokenPayload.get("aud")) || pom.contains(tokenPayload.get("azp"))){
    return true;
    }else{
    System.out.println("\n\n\tCheck audience failed - audiences differ\n");
    return false;
    }
    }
    System.out.println("\n\n\tCheck audience failed - required information missing in the token\n");
    return false;
    }

    // verify google token payload :
    private boolean doTokenVerification(final Map<String,String> tokenPayload){
    if(tokenPayload!=null){
    return verifyEmail(tokenPayload) // check that email address is verifies
    && checkExpirationTime(tokenPayload) // check that token is not expired
    && checkAudience(tokenPayload) // check audience
    ;
    }
    return false;
    }

  4. #4
    Join Date
    Mar 2017
    Posts
    4
    After analyzing my code's responses and exceptions, i have determined that my old verification with the google's token verification library for java was failing because the front end was using the different client_id then what i was expecting. [grumble, grumble] I asked them about it about a hundred times and they told me that it matches the back end. So it wasn't the fault of the google developer team, it was a mistake in communication.

    Still, i must make one complaint about the google library - it never told me why token verification was failing. It took me DAYS of pain staking effort to finally figure it out. I know they did it out of security, but still, the lack of support is galling.

  5. #5
    Join Date
    Apr 2016
    Posts
    9
    Before you can integrate Google Sign-In into your website, you must have a Google API Console project. In the project, you create a client ID, which you need to call the sign-in API.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles