How to create OAuth in Apigee to an API with existing SAS

Hi All,

I need help in the authentication. I have existing API that has SAS on it, it works fine with the response when I add to Apigee API proxy but when I apply Authentication inside apigee I am getting an error.
My goal is to manage the authentication inside Apigee like I will be using the access_token I generated.

Thank you.

{
 "error": {
 "code": "DirectApiRequestHasMoreThanOneAuthorization",
 "message": "The request has both SAS authentication scheme and 'Bearer' authorization scheme. Only one scheme should be used."
 }
}
Solved Solved
0 2 989
1 ACCEPTED SOLUTION

If I understand correctly, You're doing what we might call "security mediation."

You want the Apigee API Proxy to use one kind of Authentication - oauth tokens.

And you want to access the backend using a SAS token.

Do I have that right?

I believe the error message you provided, "The request has both SAS authentication scheme and 'Bearer' authorization scheme. Only one scheme should be used." is something that is generated by a Microsoft Azure Endpoint.

It is telling you that it found both an Authorization header, as well as a SAS signature on the request. And that Microsoft endpoint is saying "only one of those should be used."

You may not be clear - Why does the azure endpoint receive both the header and the signature?

After the Apigee API Proxy validates the token which is passed in the inbound Authorization header, Apigee "proxies the request" to the backend. By that I mean the Apigee runtime creates a new request, with the same shape as the inbound request - same URL, same headers, and so on. As a result, the backend system receives a signature and an Authorization header.

To send only the signature and not the header you must configure the API Proxy to send a modified request to the backend. This is pretty simple to do, using the AssignMessage policy. It looks like this:

<AssignMessage name='AM-RemoveAuthzHeader'/>
  <Remove>
    <Headers>
      <Header name='Authorization'/>
    </Headers>
  </Remove>
</AssignMessage>

Attach that to the request flow (either proxy request or target request) after the policy that verifies the token.

BTW here is a screencast showing you the same principle... modifying the request... except in the screencast I remove a query parameter, rather than a header.

View solution in original post

2 REPLIES 2

If I understand correctly, You're doing what we might call "security mediation."

You want the Apigee API Proxy to use one kind of Authentication - oauth tokens.

And you want to access the backend using a SAS token.

Do I have that right?

I believe the error message you provided, "The request has both SAS authentication scheme and 'Bearer' authorization scheme. Only one scheme should be used." is something that is generated by a Microsoft Azure Endpoint.

It is telling you that it found both an Authorization header, as well as a SAS signature on the request. And that Microsoft endpoint is saying "only one of those should be used."

You may not be clear - Why does the azure endpoint receive both the header and the signature?

After the Apigee API Proxy validates the token which is passed in the inbound Authorization header, Apigee "proxies the request" to the backend. By that I mean the Apigee runtime creates a new request, with the same shape as the inbound request - same URL, same headers, and so on. As a result, the backend system receives a signature and an Authorization header.

To send only the signature and not the header you must configure the API Proxy to send a modified request to the backend. This is pretty simple to do, using the AssignMessage policy. It looks like this:

<AssignMessage name='AM-RemoveAuthzHeader'/>
  <Remove>
    <Headers>
      <Header name='Authorization'/>
    </Headers>
  </Remove>
</AssignMessage>

Attach that to the request flow (either proxy request or target request) after the policy that verifies the token.

BTW here is a screencast showing you the same principle... modifying the request... except in the screencast I remove a query parameter, rather than a header.

Hi Dino,

Thanks a lot, works like charm!