I am trying to raise fault for invalid_access_token but the fault.name doesnt match

Hi,

I am trying to raise fault for the error below on apigee edge;

{
    "fault": {
        "faultstring": "Invalid Access Token",
        "detail": {
            "errorcode": "keymanagement.service.invalid_access_token"
        }
    }
}
In the preflow, I have tried to raise fault as shown below;
<Step>
  <Name>OA2-VerifyAccessToken</Name>
</Step>
<Step>
  <Name>RF-Oauth2</Name>
  <Condition>fault.name Matches "InvalidAccessToken" or fault.name Matches "invalid_access_token" or fault.name Matches "access_token_expired"</Condition>
</Step>
 
Unfortunately, none of the conditions gets the error thrown and thus I am not able to catch and customize the error message being sent back to the API.
 
My raise fault XML code is as below;
 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RaiseFault async="false" continueOnError="false" enabled="true" name="RF-Oauth2">
  <DisplayName>RF-Oauth2</DisplayName>
  <Properties/>
  <FaultResponse>
    <Set>
      <Headers>
        <Header name="Content-Type">application/json</Header>
        <Header name="Cache-Control">no-store</Header>
      </Headers>
      <Payload contentType="application/json;charset=UTF-8">
{
  "responseId": "{OCID}",
  "errorCode": "401",
  "errorMessage": "Invalid or Expired Access token",
  "timestamp": "{NOW}"
}
</Payload>
      <StatusCode>500</StatusCode>
      <ReasonPhrase>Invalid or Expired Access token</ReasonPhrase>
    </Set>
  </FaultResponse>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>
 
I have also tried to add the following fault rule but still it doesn't work;
 
<FaultRule name="invalid_access_token">
  <Step>
    <Name>RF-Oauth2</Name>
  </Step>
  <Condition>(fault.name = "invalid_access_token")</Condition>
</FaultRule>
 
My question here then is, how do I raise fault for "errorcode": "keymanagement.service.invalid_access_token" ?
 
Remember,  the condition (fault.name Matches "invalid_access_token") does not work for my case on APIGEE edge.
Solved Solved
0 3 2,053
2 ACCEPTED SOLUTIONS

Hi spencerbenson

In your flow, this is probably wrong: 

 

<Step>
  <Name>OA2-VerifyAccessToken</Name>
</Step>
<Step>
  <Name>RF-Oauth2</Name>
  <Condition>fault.name Matches "InvalidAccessToken" or fault.name Matches "invalid_access_token" or fault.name Matches "access_token_expired"</Condition>
</Step>

 

The reason for this is, the OAuthV2 policy will automatically and implicitly raise a fault, when the token is invalid. You don't need to use RaiseFault there, to raise a fault.  In fact, in the case in which the token is not valid, the RF-Oauth2 step will never get executed**, because the Apigee flow will enter fault state, and processing immediately transfers to the FaultRules. 

**The exception is if you have continueOnError='true' in your OA2-VerifyAccessToken policy.  You probably don't want that though. 

It sounds like what you want to do is override the error message that gets sent back to the client application when a token is invalid. Is that right?  I am inferring that because of the message payload you have in your RF-Oauth2 policy.   We don't call that "raising a fault". Really that's just overriding the error message. 

And the correct way to do that in Apigee is in a FaultRule.  You can follow this simple example in the documentation.

You showed a particular FaultRule, and that looks right as far as it goes, but, that rule must be configured correctly in the Apigee proxy in order for it to be evaluated in fault processing.  You didn't show how you attached the policy; I'm guessing there's something wrong with that, which is why you see it "not working". 

Some other feedback

  1. it is an anti-pattern to use a RaiseFault within a FaultRule.  Just use AssignMessage instead. You can set the message payload. 
  2. Don't use status code 500 for "invalid token".  That's a 4xx error.  401 or 400 or something similar.
  3. In the AssignMessage you can set variables like NOW and so on, with a formatted time string, via AssignVariable

Let me know if any of this is not clear.

View solution in original post

Hi @dchiesa1 , Thank you for pointing me in the right direction. And for clarifying when to use either RaiseFault and when to use AssignMessage to return an error message to the user. 

View solution in original post

3 REPLIES 3

Hi spencerbenson

In your flow, this is probably wrong: 

 

<Step>
  <Name>OA2-VerifyAccessToken</Name>
</Step>
<Step>
  <Name>RF-Oauth2</Name>
  <Condition>fault.name Matches "InvalidAccessToken" or fault.name Matches "invalid_access_token" or fault.name Matches "access_token_expired"</Condition>
</Step>

 

The reason for this is, the OAuthV2 policy will automatically and implicitly raise a fault, when the token is invalid. You don't need to use RaiseFault there, to raise a fault.  In fact, in the case in which the token is not valid, the RF-Oauth2 step will never get executed**, because the Apigee flow will enter fault state, and processing immediately transfers to the FaultRules. 

**The exception is if you have continueOnError='true' in your OA2-VerifyAccessToken policy.  You probably don't want that though. 

It sounds like what you want to do is override the error message that gets sent back to the client application when a token is invalid. Is that right?  I am inferring that because of the message payload you have in your RF-Oauth2 policy.   We don't call that "raising a fault". Really that's just overriding the error message. 

And the correct way to do that in Apigee is in a FaultRule.  You can follow this simple example in the documentation.

You showed a particular FaultRule, and that looks right as far as it goes, but, that rule must be configured correctly in the Apigee proxy in order for it to be evaluated in fault processing.  You didn't show how you attached the policy; I'm guessing there's something wrong with that, which is why you see it "not working". 

Some other feedback

  1. it is an anti-pattern to use a RaiseFault within a FaultRule.  Just use AssignMessage instead. You can set the message payload. 
  2. Don't use status code 500 for "invalid token".  That's a 4xx error.  401 or 400 or something similar.
  3. In the AssignMessage you can set variables like NOW and so on, with a formatted time string, via AssignVariable

Let me know if any of this is not clear.

Hi @dchiesa1 , I just followed what you mentioned above, but I am not getting the error message which I created when the access token is invalid. PFB the proxy code,

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
<FaultRules>
<FaultRule name="InvalidAccessToken">
<Step>
<Name>AM_Unauthorized</Name>
</Step>
<Condition>(fault.name = "InvalidAccessToken")</Condition>
</FaultRule>
</FaultRules>
<PreFlow name="PreFlow">
<Request>
<Step>
<Name>OAuth-v2_VerifyAccessToken</Name>
</Step>
</Request>
<Response/>

Below is the Assign message policy,

<AssignMessage async="false" continueOnError="false" enabled="true" name="AM_Unauthorized">
<DisplayName>AM_Unauthorized</DisplayName>
<Add>
<Headers>
<Header name="ohh hoo! Not allowed"/>
</Headers>
</Add>
<Set>
<Payload>
{
"error":
{
"errorcode":401,
"errormessage":"Unauthorized"
}
}
</Payload>
<Verb/>
<StatusCode>401</StatusCode>
<ReasonPhrase>Unauthorized</ReasonPhrase>
</Set>

Hi @dchiesa1 , Thank you for pointing me in the right direction. And for clarifying when to use either RaiseFault and when to use AssignMessage to return an error message to the user.