重定向时的授权标头

24

在Chrome、IE和Firefox中,当跟随303响应的重定向时,Authorization头将被包含。
当请求内部服务响应Location头中有签名的S3 URL时,这是一个问题。
S3将会响应一个400错误,并且无法确定使用哪种身份验证方法。

内部服务请求

GET INTERNAL_SERVICE HTTP/1.1
Pragma: no-cache
Origin: https://example.com
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8,da;q=0.7,de;q=0.6
Authorization: Bearer g6YQjOy3BDu32es8xKdMRNpcQ2Fkrh5NG7y5fDs5
Accept: application/json, text/plain, */*
Cache-Control: no-cache
Authority: example.com
Host: example.com
Connection: close

响应

HTTP/1.1 303 See Other
Date: Tue, 13 Mar 2018 08:55:12 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Connection: close
Server: nginx
location: S3_SIGNED_URL
Cache-Control: no-cache, private
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Accept, Authorization, X-                        
Requested-With
Access-Control-Max-Age: 28800

请求S3

GET S3_SIGNED_URL HTTP/1.1
Pragma: no-cache
Origin: https://example.com
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8,da;q=0.7,de;q=0.6
Authorization: Bearer g6YQjOy3BDu32es8xKdMRNpcQ2Fkrh5NG7y5fDs5
Accept: application/json, text/plain, */*
Cache-Control: no-cache
Authority: example.com
Host: BUCKET_NAME.s3.eu-central-1.amazonaws.com
Connection: close

响应

HTTP/1.1 400 Bad Request
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
x-amz-request-id: REQUEST_ID
x-amz-id-2: AMZ_ID
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Tue, 13 Mar 2018 09:06:41 GMT
Connection: close
Server: AmazonS3

<?xml version="1.0" encoding="UTF-8"?>
<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>Bearer g6YQjOy3BDu32es8xKdMRNpcQ2Fkrh5NG7y5fDs5</ArgumentValue>
   <RequestId>REQUEST_ID</RequestId>
   <HostId>HOST_ID</HostId>
</Error>

是否有一种方法可以指示浏览器忽略掉Authorization头部,或者强制S3忽略该头部?


1
如果您使用不同的重定向代码,例如302或307会怎样?无论如何,浏览器跨源发送“Authorization”标头似乎都是错误的...存储桶上配置了CORS吗? - Michael - sqlbot
1
我们尝试从AllowedHeader中删除标头,但浏览器仍然发送标头,然后我们遇到了CORS冲突。浏览器似乎根本没有向S3发送预检请求。 - Multiply
1
@MortenHauberg 你最终解决了这个问题吗?我们也遇到了完全相同的问题。 - Vinnie
2
到了2021年,我仍然找不到这个问题的答案。将授权标头重定向到跨源资源是一种极其不安全的设计,随着越来越多地使用S3,我不断遇到这个问题。 - ezekg
3
到了2022年,我仍然找不到答案... - janfabian
显示剩余5条评论
3个回答

2

1
我通过配置我的后端来解决了这个问题,以支持替代的身份验证头(X-App-Authorization)并从中获取令牌。
显然,这并不理想,因为(1)应用程序现在必须使用非标准的头部至少对受影响的端点进行操作,而且(2)应用程序的授权令牌仍然被“泄漏”给AWS。
如果这些问题对您的应用程序是无法接受的,您可以通过使用类似NGINX的“X-Accel-Redirect”来解决问题,并让反向代理透明地流式传输S3下载。当然,这种方法比直接重定向到S3效率要低一些。

如果您正在使用API网关与Cognito授权集成,这种方法同样适用。 - undefined

0
我终于找到了解决办法。
创建一个如下的拦截器。

import { Injectable, Injector } from '@angular/core';
import { HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';

@Injectable({
  providedIn: 'root',
})
export class TokenInterceptorService implements HttpInterceptor {
  constructor(private injector: Injector) {}

  intercept(req, next: HttpHandler) {
    if (req.headers.lazyInit.headers.get('x-skip-auth') != null) {
      debugger;
      req = req.clone({ headers: req.headers });
      var indexAuthorization = req.headers.lazyUpdate.indexOf(
        req.headers.lazyUpdate.filter(x => x.name == 'Authorization')[0]
      );
      delete req.headers.lazyUpdate[indexAuthorization];

      req.headers.lazyInit.headers.delete("x-skip-auth");
    }
    return next.handle(req);
  }
}

让我们开始一个请求吧 :)

   this.http.post(
        'url',
        {},
        {
          headers: {
            "x-event-id" : eventId,
            "x-skip-auth" : 'true'
          },
        }
      )

我们在做什么?
1. 拦截器寻找 "x-skip-auth" 头部键。 2. 如果请求中有 "x-skip-auth" 头部,拦截器会从头部中移除 Authorization 头部。
祝好运!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接