OAuthV2 operation GenerateAccessToken

We are looking to create a pass through proxy for a SOAP service which has its own internal security service to generate tokens. I am trying to use the GenerateAccessToken to cache the token in Apigee. The credentials in use are associated with an app and product so are valid in terms of accessing the service. The call to the backend soap service returns the access token in a soap envelope and I have managed to extract the token successfully but the issue I am facing is related to the client_id as the only option is to set the request.formparam.client_id in the request but this results in the backend service failure as the soap payload is replaced by the formparams. I need to be able to reference the client_id in another location for this policy to pass but the documentation states that the only valid value for the ClientId element is - request.formparam.client_id. I have even used an assign message policy to try and set the variable (the variable is set as expected), but the policy still fails.

The trace shows variable read/assigned:

oauth_external_authorization_status oauthV2.failed oauthV2.OA2-GenerateAccessToken.failed oauthV2.OA2-GenerateAccessToken.fault.name oauthV2.OA2-GenerateAccessToken.fault.message apigee.metrics.policy.OA2-GenerateAccessToken.timeTaken 

true
true
 true
 oauth.v2.InvalidClientIdentifier
 Invalid client identifier {0}
368832

 

I have used jwt.io to validate the token and there is no issue with that. 

Is there anything that anybody knows of that could help with this issue? 

0 4 469
4 REPLIES 4

I am not clear on this part

this results in the backend service failure as the soap payload is replaced by the formparams

In your case, the experience of using the OAuthV2/GenerateAccessToken policy is probably a bit klunky because ... the policy expects the client id to be present in the request formparams, while....maybe in your case the actual request uses content-type:text/xml or similar, and cntains a SOAP request.

But while it seems like it might be klunky, it should just work. You need to overwrite the request payload to contain a form payload, with the required formparams, prior to executing the OAuthV2/GenerateAccessToken. Maybe you tried doing this. If so, can you show the AssignMessage policy configuration you used?I expect it should look something like this:

 

 

<AssignMessage name='AM-Overwrite'>
  <AssignTo>request</AssignTo>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <Remove>
    <Payload/>
    <Headers/>
  </Remove>
  <AssignVariable>
    <Name>blob</Name>
    <Template>{variable_containing_client_id}:{variable_containing_client_secret}</Template>
  </AssignVariable>
  <Set>
    <Headers>
      <Header name='content-type'>application/x-www-form-urlencoded</Header>
      <Header name='Authorization'>Basic {encodeBase64(blob)}</Header>
    </Headers>
    <FormParams>
      <FormParam name='grant_type'>client_credentials</FormParam>
    </FormParams>
    <Verb>POST</Verb>
  </Set>
</AssignMessage>

 

 

...but it might be different depending on how you configure your OAuthV2 policy.

If for some reason you need the XML payload of the original request, then you can save it by copying the request message to a different message, prior to overwriting it with the form payload. You can use the AssignMessage with the Copy element to do this.  If this is not clear, let me know, I'll explain further.

An error message like "Invalid client identifier {0}" seems to be a bug. That {0} seems like it should be filled with the actual client id you passed. But in any case we can surmise that whatever you specified for the client id, is not valid.

Is it possible that you are assuming the client_id must be specified in the form param, but really the runtime policy is looking for the client id in the Authorization header?

I have had to utilise a different backend service that will accept form params. I did try basic auth configuration but that still did not work. I have a working process now with the form params. 

I'm glad to hear you've solved it.

I can see multiple errors.

The first one 

oauth_external_authorization_status oauthV2.failed oauthV2.OA2- is true, so you need to ensure external_access_token is having value of token.

ref: 

Then for invalid client try to send the Base 64 encoded credentials in Authorization header.