Implementing Fault rules for Basic Auth policy and Verify Apikey

I am trying to implement faultrules for Basic Authentication Policy and apikey policy. However, I get an error while saving my proxy. (attached screenshot). When i remove the faultrules section, the proxy is saved successfully. Are fault rules supported for Basic Authentication and apikey policies? If yes, can someone point out if I am doing something wrong.

Below is the fault rule configuration in my flow

<Step>  
	<FaultRules>
		<FaultRule>
            <Step>
                <Name>Invalid-Auth-Header</Name>
                <Condition>(BasicAuthentication.Basic-Authentication-1.failed = true)</Condition>
            </Step>
        </FaultRule>
	<FaultRule name="Invalid Client Id">
            <Step>
                <Name>Invalid-Client-Id-or-secret</Name>
                <Condition>(fault.name = "InvalidApiKey") or (fault.detail.errorcode = "oauth.v2.InvalidApiKey")</Condition>
            </Step>
        </FaultRule>

    </FaultRules>
    <Name>Basic-Authentication-1</Name>
</Step>

Solved Solved
0 14 2,578
1 ACCEPTED SOLUTION

That looks correct. You should be able to use the Trace tool to resolve this. In the Trace tool you should see something like this. Notice that VerifyAPIKey has an error.

If you select the first diamond with a "T" in it after the VerifyAPIKey, you should see in the trace window that the error is of type "Invalid APIKey".

If you select your Invalid-Client-id-or-secret policy, you should see that the fault.name is InvalidApiKey.

There is an example of handling this error in the doc at http://apigee.com/docs/api-services/content/fault-handling

1012-screen-shot-2015-08-27-at-102533-am.png

View solution in original post

14 REPLIES 14

I guess I got it a bit wrong. I tried putting it in the fault rules for the proxy endpoint and was able to save it. But I have an issue while executing the fault rule for apikey. The fault details are empty and the failed flag is not set to true, when i check my trace. Hence my fault rule is not getting executed. Any pointers on how to fix this?

oauthV2.Verify-Consumer-Key.failed false

oauthV2.Verify-Consumer-Key.fault.cause <blank>

oauthV2.Verify-Consumer-Key.fault.name <blank>

Try accessing them as:

oauthV2.verify-api-key.*

as shown below:

<AssignMessage async="false" continueOnError="false" enabled="true" name="Invalid-Client-Id-or-secret">
    <DisplayName>Invalid-Client-Id-or-secret</DisplayName>
    <Properties/>
    <Set>
        <Payload contentType="text/plain">
            <ExtractFName>{fault.name}</ExtractFName>
            <ExtractFailed>{oauthV2.verify-api-key.failed}</ExtractFailed>
            <ExtractCause>{oauthV2.verify-api-key.fault.cause}</ExtractCause>
            <ExtractName>{oauthV2.verify-api-key.fault.name}</ExtractName>
        </Payload>
        <StatusCode>401</StatusCode>
        <ReasonPhrase>KeyFault</ReasonPhrase>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>

That will write them to the payload of the response, but you can use that type of access them in any way that you want.

Stephen

The problem I have is that the condition for the fault rule is not getting satisfied, so wont get to the assignmessage policy itself. Can you pls let me know how to resolve htis. This is my faultrule -

	<FaultRule name="Invalid Client Id">
            <Step>
                <Name>Invalid-Client-Id-or-secret</Name>
                <Condition>(fault.name = "InvalidApiKey") or (fault.detail.errorcode = "oauth.v2.InvalidApiKey")</Condition>
            </Step>
        </FaultRule>

I always get the default response -

{ "fault": { "faultstring": "Invalid ApiKey", "detail": { "errorcode": "oauth.v2.InvalidApiKey" } } }

That looks correct. You should be able to use the Trace tool to resolve this. In the Trace tool you should see something like this. Notice that VerifyAPIKey has an error.

If you select the first diamond with a "T" in it after the VerifyAPIKey, you should see in the trace window that the error is of type "Invalid APIKey".

If you select your Invalid-Client-id-or-secret policy, you should see that the fault.name is InvalidApiKey.

There is an example of handling this error in the doc at http://apigee.com/docs/api-services/content/fault-handling

1012-screen-shot-2015-08-27-at-102533-am.png

@sgilson This is what I see in the trace tool. the failed flag is also showing as false. I have ensured that i deleted two characters from the api key so that its invalid

Attachment

What do you see when you select the "T" in the diamond just after the VerifyAPIKey policy?

I see ((error.state equals PROXY_REQ_FLOW) or (error.state equals PROXY_RESP_FLOW)) evaluated to true and the next T has ("default" equals proxy.name) evaluated to True.

@sgilson I figured out that, only the last faultrule defined is getting executed. For eg: if i changed the order of faultrules 1st BasicAuth error 2nd API key error, i get the apikey fault custom response. If i provide invalid basicauth header, none of the faultrules get executed and the default fault response from teh policy is received. any pointers on what could be the issue?

That is as designed. From the doc:

"When a fault rule's condition evaluates to true, the policies specified in the rule execute. If multiple fault rules have a condition that evaluates to true, then the last of those fault rules executes. This is different behavior from Route Rules and Flow conditions, which execute the first of the set for which a condition evaluates to true."

@sgilsonYes, I am aware that the faultrules execute bottom-up. What is very strange is that, the conditions in both faultrules are different and cannot be satisfied at the same time.

These are my faultrules. Its very strange that the condition for invalid api key is not getting satisfied and the step "Invalid Client Id" is not getting executed. If i give an invalid apikey, both the faultrules are not getting executed. and the trace flow only shows "Invalid Basic Auth Credentials" as skipped, not sure why the other rule is neither executed nor shown as skipped

    <FaultRules>
        <FaultRule name="Invalid Client Id">
            <Step>
                <Name>Invalid-Client-Id-or-secret</Name>
                <Condition>(fault.name = "InvalidApiKey")</Condition>
            </Step>
        </FaultRule>
<FaultRule name="Invalid Basic Auth credentials">
            <Step>
                <Name>Invalid-Auth-Header</Name>
                <Condition>(fault.name = "InvalidBasicAuthenticationSource")</Condition>
            </Step>
        </FaultRule>
    </FaultRules>

My apologies - I think I missed something. Take the <Condition> tag out of the <Step> tag and try it:

<FaultRules>
        <FaultRule name="InvalidClientId">
            <Step>
                <Name>Invalid-Client-Id-or-secret</Name>
            </Step>
            <Condition>(fault.name = "InvalidApiKey")</Condition>
        </FaultRule>
        <FaultRule name="InvalidBasicAuthcredentials">
            <Step>
                <Name>Invalid-Client-Id-or-secret</Name>
            </Step>
                <Condition>(fault.name = "DeveloperStatusNotActive")</Condition>
        </FaultRule>

@sgilson Thanks a ton, that worked..

>and the trace flow only shows "Invalid Basic Auth Credentials" as skipped, not sure >why the other rule is neither executed nor shown as skipped

This is because both of your fault rules do not have conditions, and so both are evaluated to true. But since Fault Rules are executed bottoms-up, the bottom Fault Rule is evaluated as true first and so the other Fault Rule never executes. As

@sgilson also implicitly noted, the confusion is probably due to the conditions in your code being applied at the step level vs. the Fault Rule level.