Add headers (cors) to 401(etc) invalid token response

Not applicable

The title is probably enough.

Preflight OPTIONS are working but we need to set the cors headers on Apigee's oauth errors. Andrew

Solved Solved
1 10 2,987
1 ACCEPTED SOLUTION

Not applicable

Hi @Chris Covney , You can add the header Access-Control-Allow-Origin for the fault raised when Oauth policy is failed or put this header in the #DefaultFaultRule as it is needed for all faults (http://apigee.com/docs/api-services/content/fault-handling)

Whether its error or successful response the above header is needed for all the actual calls .

Check this http://community.apigee.com/questions/3138/cors-policy-in-my-api-proxy-when-using-oauth-20.html#comm... for reference .

View solution in original post

10 REPLIES 10

Not applicable

You should be able to do this via an Assign Message policy:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="[Put name here]">
    <DisplayName>[Put display name here]</DisplayName>
    <FaultRules/>
    <Properties/>
     <Set>
            <Headers>
		<Header> [Put CORS header here] </Header>
		<Header> [Any other header] </Header>
	    </Headers>
          <Payload contentType="application/json">\{ "error": "Put error response here"} </Payload>
            <StatusCode>401</StatusCode>
            <ReasonPhrase>[Put Reason Code Here]</ReasonPhrase>
        </Set>
</AssignMessage>

You could follow this by a Raise Fault policy if you want to return immediately.

Be sure to put sufficient <Condition></Condition> clauses in your flow code to handle this situation.

Please let me know if that does what you intended it to do. Otherwise, I'll be glad to look into it further.

Hi Michael,

This does not do it for the Apigee Policy-Generated errors (like when an invalid auth code is passed to the access_token endpoint during the authorization_code flow). When a policy throws an error, Apigee strips all the content from the request thus far and returns only the policy's own error message.

Any idea how to force Apigee to honor the CORS headers previously added via an assign message policy like the one you referenced above?

Thanks!

Chris

Just FYI, this is slightly different than the issue expressed in:http://community.apigee.com/questions/657/oauth2-and-cors.html

because I see my add cors policy is executed, but its content is removed when a policy throws its own error.

So it seems most of these solutions simply set the CORS headers to "*" allowing any, possibly malicious, user to access them. I see the logic in that these are simply error messages so the concern is lowered, but it feels like a possible security flaw. Any thoughts? And is there an alternative?

Correct! Setting the Access-Control-Allow-Origin header to "*" effectively disables CORS. Which eliminates its protections.

The ideal thing is for people to use the appropriate hostname in that field.

Apigee is working on a policy that will provide better, more nuanced CORS support.

Stay tuned.

Not applicable

Hi @Chris Covney , You can add the header Access-Control-Allow-Origin for the fault raised when Oauth policy is failed or put this header in the #DefaultFaultRule as it is needed for all faults (http://apigee.com/docs/api-services/content/fault-handling)

Whether its error or successful response the above header is needed for all the actual calls .

Check this http://community.apigee.com/questions/3138/cors-policy-in-my-api-proxy-when-using-oauth-20.html#comm... for reference .

the default fault rule (as a child element of the proxy endpoint) containing a step with the add-cors policy worked!

pretty sure i love you right now, maruti. just sayin.

jovaniac
Participant II

hey guys, I implemented something like that and it served me correctly.

In the proxy enpoint we must place in the preflow the next call of a Flowcallout to invoke a sharedflow which will have the policy of CORS

<PreFlow name="PreFlow">
  <Request>
    <Step>
      <Name>FC-CORS</Name>
    </Step>
    <Step>
      <Name>FC-OAuth2</Name>
    </Step>
  </Request>
  <Response/>
</PreFlow>

Definition of flowcallout, where we invoke the sharedflow

<FlowCallout name="FC-CORS">
  <SharedFlowBundle>OPTIONS-CORS-Headers-Response</SharedFlowBundle>
</FlowCallout>

definition of sharedflow

<SharedFlow name="default">
  <Step>
    <Name>OPTIONS-CORS-Headers-Response</Name>
    <Condition>request.verb == "OPTIONS"</Condition>
  </Step>
</SharedFlow>

definition of the policy of raisefault, where we will indicate the headers of Access-Control-Allow-Origin with * that will allow the invocation from our browser:

<RaiseFault  name="OPTIONS-CORS-Headers-Response">
	  <Set>
	  <Headers>
	  <Header name="Access-Control-Allow-Origin">*</Header>
	  <Header name="Access-Control-Allow-Headers">origin, 
x-requested-with, accept, ucsb-api-key, ucsb-api-version, 
authorization</Header>
	  <Header name="Access-Control-Max-Age">3628800</Header>
	  <Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE</Header>
	  </Headers>
	  <Payload contentType="text/plain"/>
	  <StatusCode>200</StatusCode>
	  <ReasonPhrase>OK</ReasonPhrase>
	  </Set>
	  </FaultResponse>
	  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>

Regards

We got this working by adding CORS Policy on the RaiseFault Policy erroring out. Like this

<FaultResponse>
        <Set>
            <Headers>
                <Header name="Access-Control-Allow-Origin">*</Header>
                <Header name="Access-Control-Allow-Credentials">true</Header>
                <Header name="Access-Control-Allow-Headers">
                    origin, x-requested-with, accept, content-type, authorization
                </Header>
                <Header name="Access-Control-Max-Age">3628800</Header>
                <Header name="Access-Control-Allow-Methods">GET, PUT, POST, DELETE, OPTIONS</Header>
            </Headers>
            <StatusCode>404</StatusCode>
            <ReasonPhrase>Not Found</ReasonPhrase>
            <Payload contentType="application/json">
                {
                "Code" : "404" ,
                "Message" : "Invalid or missing resource (path)."
                }
            </Payload>
        </Set>
    </FaultResponse>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</RaiseFault>

Is there a way we could prevent this hardcoding the CORS policies in the Raise Faults and override Apigees default behavior of overriding previously sent CORS Policies?.

@marshg@google.com - FYI

I know this is an old question but it's valid and still worth answering.

Today there is no good way to avoid what you are doing.

Apigee is working on a policy to assist with this, so that you don't need to sprinkle CORS stuff in various policies around your proxy. I have no expected time of availability of that policy, but we're working on it.