apex icon indicating copy to clipboard operation
apex copied to clipboard

Is Apex working for Google OpenId?

Open jeroenvandijk opened this issue 4 years ago • 3 comments

I'm interested in using the OpenId part outside of Apex (*). I have been able to get your code working with Cognito. For Google It seems I'm getting an incomplete JWT token (see below). I'm not entirely sure how to test this with Apex (I would have to dive into the application structure). So I'm hoping you could confirm or deny that Google OpenId was working for you? If not, I might actually propose a fix later on.

Can you confirm you had success with Google? If so, I have broken something.

Error after receiving the JWT token (just before validation):

java.text.ParseException: Invalid serialized unsecured/JWS/JWE object: Missing second delimiter
	at com.nimbusds.jose.JOSEObject.split(JOSEObject.java:228)
	at com.nimbusds.jwt.SignedJWT.parse(SignedJWT.java:110)
	at sun.reflect.GeneratedMethodAccessor107.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:167)
	at clojure.lang.Reflector.invokeStaticMethod(Reflector.java:332)
	at juxt.apex.alpha.oauth2.jwt$signed_jwt.invokeStatic(jwt.clj:23)
	at juxt.apex.alpha.oauth2.jwt$signed_jwt.invoke(jwt.clj:20)

(*) I would love to use Apex for other use cases though!

jeroenvandijk avatar Apr 16 '20 09:04 jeroenvandijk

I haven't tested with Google OpenId yet. It would be interesting to know why it doesn't work. Nimbus has worked well so far (I've wanted to use something that uses native JDK crypto rather than buddy which uses Bouncy Castle). But there are alternatives such as Auth0's Java libs. See https://jwt.io/ too.

malcolmsparks avatar Apr 16 '20 09:04 malcolmsparks

Ok I haven't found official proof, but I think the access token of Google aren't meant to be valid JWT's and they don't have to be apparantly. This is mentioned by Okta: "Although not mandated by the OIDC spec, Okta uses JWTs for access tokens as (among other things) the expiration is built right into the token."

Also Google itself only talks about "validating an id token"

A valid JWT token requires three parts, Google gives a string of two parts. So I tried multiple libraries and they all, rightfully, complain about the missing signature. I also didn't find a way to decode parts of this string into something meaningful.

Only the API call of Google gives some feedback in the form of json: https://oauth2.googleapis.com/tokeninfo?access_token=<non-expired-token-here>

{
  "azp": "***",
  "aud": "***",
  "sub": "***",
  "scope": "openid",
  "exp": "1587046705",
  "expires_in": "2785",
  "access_type": "online"
}

So could it be that the code here:

(merge
 (when id-token
   {:apex.oic/id-token-claims (jwt/claims id-token-jwt)})
 {:apex.oic/access-token-claims (jwt/claims access-token-jwt)
  :apex.oic/access-token access-token}))

Should actually be:

(merge
 (when id-token
   {:apex.oic/id-token-claims (jwt/claims id-token-jwt)})
 (when access-token-claims
   {:apex.oic/access-token-claims access-token-claims})
 {:apex.oic/access-token access-token})

I'll continue assuming the later and wrap the validation of the access token in a try/catch to handle these exceptions.

jeroenvandijk avatar Apr 16 '20 13:04 jeroenvandijk

This is really useful. I suggest you continue on your fork until you're happy you've got the Google idp working - we can then compare the two versions, I can retest on the current list of other providers, and we can then merge. I'm sure Google are compliant with the standards and I've made erroneous assumptions here, and I'm more than happy to be corrected.

malcolmsparks avatar Apr 17 '20 09:04 malcolmsparks