Reputation: 4136
I'm using token authentication in DRF and for a certain API call, want to redirect to S3 (using a URL like https://my_bucket.s3.amazonaws.com/my/file/path/my_file.jpg?Signature=MY_AWS_SIGNATURE&AWSAccessKeyId=MY_AWS_ACCESS_KEY_ID
). However, I get the following error from AWS:
<Error>
<Code>InvalidArgument</Code>
<Message>Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified</Message>
<ArgumentName>Authorization</ArgumentName>
<ArgumentValue>Token a3f61c10592272399099882eb178bd4b755af5bf</ArgumentValue>
<RequestId>E4038228DD1E6330</RequestId>
<HostId>9c2xX59cugrR0CHjxQJR8IBE4MXBbNMX+wX2JdPJEuerkAftc32rufotM7COKLIavakByuRUXOo=</HostId>
</Error>
It's clear why this happens--the Authorization
header with DRF's token is propagated with the redirect and S3 doesn't like it.
After researching and trying a million ways to get rid of that header, I gave up and decided to try and override the header with an S3 value: AWS MY_AWS_SIGNATURE:MY_AWS_ACCESS_KEY_ID
, after which I get a different error:
<Error>
<Code>InvalidArgument</Code>
<Message>Unsupported Authorization Type</Message>
<ArgumentName>Authorization</ArgumentName>
<ArgumentValue>Token a3f61c10592272399099882eb178bd4b755af5bf</ArgumentValue>
<RequestId>94D5ADA28C6A5BFB</RequestId>
<HostId>1YznL6UC3V0+nCvilsriHDAnP2/h3MoDlIJ/L+0V6w7nbHbf2bSxoQflujGmQ5PrUZpNiH7GywI=</HostId>
</Error>
As you can see, the end result is the same--even if I override the Authorization
header in my response, it still keeps the original DRF token authentication value.
# relevant portion of my response construction
headers = {'Location': 'https://my_bucket.s3.amazonaws.com/my/file/path/my_file.jpg',
'Authorization': 'AWS %s:%s' % (params['AWSAccessKeyId'], params['Signature'])}
return Response(status=status.HTTP_302_FOUND, headers=headers)
So, my question is, how can the Authorization
header in a DRF response be either removed or overridden?
Upvotes: 6
Views: 1947
Reputation: 640
I was using Mod Header google chrome extension to provide OAuth2 token in each API request (django REST framework browsable API). But it also include the Authorization header while making request to S3 static resource (js, css and other).
Prefered way is to use POSTMAN and turn off the the Token Authorization forwarding (I think it is by default. For me it API worked perfectly this way). But we lose the browsable API convenience.
Another is to use Requestly google chrome extension. Here we can prevent Authorization Token forwarding when browser requests of another URL (like https://.s3.amazonaws.com/).
configure Requestly like this. (Below is a example IP with PORT we can add this as an condition before applying Authorization in request header. Thus like of S3 do not give error and static data is served properly.)
Upvotes: 1
Reputation: 469
Redirecting the Authorization
header is the responsibility of the client (eg. browsers, cURL, HTTP libraries/toolkits).
For example, Paw, my toolkit to query my APIs offers that kind of configuration:
So basically, major browsers are tend to redirect the Authorization
header which cause the conflict on S3.
Also I suspect you misunderstood how redirects are performed:
HTTP 301 or 302
response to the client, containing the new Location
header (the request is not "forwarded" directly via DRF)And finally, you're not overriding any Authorization
header when you're emitting your 302
since this is the response... to the client (which can carry an Authorization
header but that's useless).
Right now, you have a bunch of solutions (thus not out of the box...):
HTTP GET
parameter (?token=blah
)The first two solutions may break in some way the consistency of your API but in some way are fair enough. They would require a custom TokenAuthentication
or get_authorization_header
(from rest_framework.authorization
).
The last one is transparent but may be totally unsuitable depending on the object your're fetching on S3 and/or your hosting constraints...
That's all I can tell you for now. As you know, I've been stuck with the same situation too. I would be so pleased if anyone could suggest a better solution.
Upvotes: 4