0
votes

I'm setting up cloud pub/sub service to receive push subscription messages on my backend by following the developer documentation.

For some reasons, the push subscription requests sent to my backend never have the "token" query parameter included, so my backend can't verify whether the push requests coming from my application or not. The following code from the developer doc is used to achieve the verification purpose:

  // Verify that the request originates from the application.
  if (req.getParameter("token").compareTo(pubsubVerificationToken) != 0) 
  {
      resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
      return;
  }

According to the doc, I've verified that the "Service Account Token Creator" permission is granted to pub/sub's signing service, as well as enabled "push endpoint authentication" option and assigned an unique string to the "Audience(optional)" field in my push subscription in pub/sub.

I wonder if I'm still missing something here, or I've mistaken the way how the token audience works? Why does the "token" value not appearing in the requests my backend received? Any inputs would be appreciated!

2
Google does not use a query parameter for authorization. Authentication is using the HTTP Authorization: bearer TOKEN header. - John Hanley
@JohnHanley Thank you for your comment. I also realized that after a few hours of struggling. They added this extra verification step in the Java code of the documentation, and the query parameter is also called "token" which made me so confused between the parameter and the actual authentication token... - Sam H

2 Answers

0
votes

As John Hanley said, the token is in the header. However, when I look your code, I don't know what do you want to "compare". The provided token change very often (because its life is very short) and you can't compare it to a reference token

But, you can extract claim information from token and then validate them. Here a snippet of Python code that I use for extracting email.

    authorization = request.headers['Authorization'][7:]
    b64_profile = authorization.split('.')[1]
    profile = base64.b64decode(b64_profile + '=' * (-len(b64_profile) % 4))
    print(json.loads(profile)['email'])
0
votes

The code snippet quoted here is meant to verify the application token. This token is defined by the application developer as an environmental variable in appengine-web.xml (line 7).

The token that properly verifies the origin of the push request is a different one. It is generated by Cloud Pub/Sub and comes in the authorization header of the push request, in the form of a JWT. This bit of code shows how to verify the JWT (you can also check out the full sample):

      // Verify and decode the JWT.
      GoogleIdToken idToken = verifier.verify(authorization);

Hope this helps clear the confusion. :-)