Unable to trap invalid_client error in Fault Rule

I have been trying so many stuff but I've really been stuck for more than a day on this issue.

I'm calling a proxy that calls GenerateAccessToken on supplying a 1) grant_type 2) client_id 3) client_secret. I can get a token but I want to return a customized response if any of these 3 parameters are invalid.

Apigees responses for invalid data in these 3 params:

{"ErrorCode" : "invalid_client", "Error" :"ClientId is Invalid"}

{"ErrorCode" : "invalid_client", "Error" :"Client credentials are invalid"}

{"ErrorCode" : "invalid_request", "Error" :"Unsupported grant type : client_credentials1"}

I have an AssignMessage policy that customizes my application's response to the sender that will be trigger based on this FaultRule:

<FaultRule name="checkErr2">

<Step> <Name>AM-IncorrectHeaderBodyInfo</Name>

<Condition> SOME CONDITION </Condition>

</Step>

</FaultRule>

What is the proper Condition I have to provide in the Fault Rule? I'm very frustrated as none of these work:

oauthV2.MyOathPolicy.failed = true

<Condition>(oauthV2.oauth-boc.failed = true) OR (oauthv2.oauth-boc.fault.name Matches "invalid") OR (oauthv2.oauth-boc.fault.cause = "ClientID is Invalid")</Condition>

The documentation on this page https://docs.apigee.com/api-platform/reference/policies/get-oauth-v2-info-policy is very inadequate, I am afraid to say.

0 7 283
7 REPLIES 7

Sorry you are finding the documentation to be inadequate. I know how frustrating it can be, figuring out fault rules and fault names. I have felt your pain.

I usually test "fault.name". Example

    <FaultRule name="invalid-key">
      <Step>
        <Name>AM-InvalidApiKey</Name>
      </Step>
      <Condition>fault.name = "InvalidApiKey" OR fault.name = "InvalidApiKeyForGivenResource"</Condition>
    </FaultRule>


Unfortunately I don't know all the fault names you'd be looking for. But you might be able to infer that using the Trace UI, and observing the fault name variable when the various fault conditions occur.

Appreciate your answer Dino. I did look at the trace log. I added the following condition:

<Condition>oauthV2.MyOathPolicy.failed is true OR fault.name = "ClientId is Invalid" OR fault.name = "invalid_client"</Condition>

But I still get the same standard error message.

@Dino-at-Google,

I tried another approach which is to use the RaiseFault policy. So this time I checked the trace and I found the following:

Under Variables oauthV2.failed = true

Under Properties oauthV2.MyOauthPolicy.failed true

But neither of these conditions succeed in triggering the RaiseFault policy.

I see {"Error":"Client credentials are invalid","ErrorCode":"invalid_client"} stored under Response Content. How may I capture this information to send a Custom response to the caller? Doesnt matter what policy I use. Can use JavaScript as well if thats possible.

So essentially the summary is this:

When there is an error in the grant_type/client_id/client_secret, Apigee generates the error in the (possibly deprecated or unconventional) format {"ErrorCode" : "ABC", "Error" :"DEF"}.

This is out of line with the regular error format { "fault" : "faultstring": "ABC", "detail" : {"errorcode" : "DEF" }}}

The page https://docs.apigee.com/api-platform/reference/policies/get-oauth-v2-info-policy *claims* that the error thrown will be {"fault":{"faultstring":"ClientId is Invalid","detail":{"errorcode":"keymanagement.service.invalid_client-invalid_client_id"}}}

But in reality that doesnt happen and we are left unable to trap that fault and do not have a workaround for this problem.

@Dino-at-Google

Have you examined "fault.name" via Trace UI?

What is the "fault.name" value in your proxy flow?

Note: Apigee Trace does not emit into the debugsession the value of every variable at every point in the flow. To examine the value of a specific variable, you can insert an specially configured AssignMessage policy as a diagnostic aid. Like this:

<AssignMessage name='AM-Diags'>
  <AssignVariable>
    <Name>doesntmatter</Name>
    <Ref>fault.name</Ref>
</AssignMessage>

This will emit into the debugsession an event of READing the fault.name variable. Then you can examine the Trace UI to see the value.

Have you done this?

What is the value of fault.name ?

Appreciate your input Dino. Here are the trace snippets

<ResponseMessage> <Content>{"Error":"Client identifier is required","ErrorCode":"invalid_client"}</Content>

....

</ResponseMessage>

<Properties>

<Property name="oauthV2.oath-GenerateAccessToken.failed">true</Property>

<Property name="oauthV2.oath-GenerateAccessToken.fault.name"></Property>

<Property name="oauthV2.oath-GenerateAccessToken.fault.cause"></Property>

</Properties>

Using the oauthV2.oath-GenerateAccessToken.failed=true condition does not work in raising the fault as explained before.

Secondly, I added the AssignMessage policy and set it to trigger 1) on the above condition 2) In DefaultFaultRule, no condition, and AlwaysEnforce = on.

Even then fault.name is blank in the trace

<Property name="oauthV2.oath-GenerateAccessToken.fault.name"></Property>

I think maybe you're still not clear on how to set Condition elements on FaultRule elements. In this article and the accompanying screencast, I hope to clarify that, for you and for anyone else who might have this question.