frp icon indicating copy to clipboard operation
frp copied to clipboard

HTTP代理设置BasicAuth鉴权后,无法通过CORS验证的问题

Open rty813 opened this issue 1 year ago • 9 comments

Bug Description

浏览器在发起跨域请求时,会先发送一个preflight预检请求。该请求是浏览器自动请求的,无法设置Authorization头,导致frp鉴权失败。失败后,请求并不送到我的后端服务器,而是由frp直接返回一个401响应。而这个响应中,并未包含Access-Control-Allow-Origin头,导致后续的请求认为跨域错误,导致无法请求成功。

image

frpc Version

0.49.0

frps Version

0.34.0

System Architecture

linux/arm/v7

Configurations

frpc http -s xxxxxxxxxxx -l 5000 -d xxxxxxxxxxxx --http_user xxxxxx --http_pwd xxxxxxxx --bandwidth_limit 200KB --locations /$(hostname) -n $(hostname)

Logs

No response

Steps to reproduce

...

Affected area

  • [ ] Docs
  • [ ] Installation
  • [ ] Performance and Scalability
  • [ ] Security
  • [ ] User Experience
  • [ ] Test and Release
  • [ ] Developer Infrastructure
  • [X] Client Plugin
  • [ ] Server Plugin
  • [ ] Extensions
  • [ ] Others

rty813 avatar Jun 06 '23 10:06 rty813

不太了解相关的背景,你期望的解决方案是什么?以及是否有其他的被广泛使用的代理提供了相应的可参考的解决方案,比如 nginx?

fatedier avatar Jun 07 '23 08:06 fatedier

我也遇到了同样的问题,正常穿透并通过nginx代理是没问题的,但是加了http_user/http_pwd就不行了

realmx avatar Jun 07 '23 20:06 realmx

不太了解相关的背景,你期望的解决方案是什么?以及是否有其他的被广泛使用的代理提供了相应的可参考的解决方案,比如 nginx?

期望可以设置Frp在遇到HttpAuth验证失败时,可以自定义401错误响应的Header,增加跨域相关的头。目前我临时的做法是,取消frp的httpAuth,而是在我自己的后端服务中添加auth验证,如果校验错误,后端服务自己在401响应中添加对应的头。

rty813 avatar Jun 09 '23 06:06 rty813

nginx应该可以通过下列方式,为401响应添加头: nginx add headers when returning 400 codes

For nginx >= 1.7.5 Append "always" to the header definition: add_header 'Access-Control-Allow-Origin' '*' always;

rty813 avatar Jun 09 '23 06:06 rty813

@rty813 如果默认就附加上 Access-Control-Allow-Origin header 会有安全风险吗?是否是一个标准的做法?

fatedier avatar Jun 09 '23 06:06 fatedier

@rty813 如果默认就附加上 Access-Control-Allow-Origin header 会有安全风险吗?是否是一个标准的做法?

这个会有一定的安全风险,对于我的使用场景下,是可以这样的,但是作为一个通用的方法应该允许用户自行设定。

rty813 avatar Jun 09 '23 06:06 rty813

可以考虑支持添加返回特定 header 的功能来解决这个问题。但是这方面的能力还是有限的,复杂的需求后面还是需要依赖 nginx 之类的代理解决。

fatedier avatar Jun 09 '23 06:06 fatedier

嗯嗯,如果能支持返回特定header就好了,感谢

rty813 avatar Jun 13 '23 10:06 rty813

其实是http请求处理顺序的问题,可以在所有请求前(不校验权限)处理预检请求:以gin框架为例

router.Use(option())
func option() gin.HandlerFunc {
	return func(c *gin.Context) {
		if c.Request.Method == "OPTIONS" {
			setCors(c.Writer) // 这里配置跨域header
			c.JSON(http.StatusOK, "Options Request!")
			c.Abort()
			return
		}

		c.Next()
	}
}

gocnpan avatar Aug 18 '23 03:08 gocnpan