哈哈,这可能就是典型的标题党了
首先说一下问题,最近正好负责微服务下的一个子项目
认证中心 UAA
认证中心基于spring-security-oauth2,选用这个框架也是为了以后的扩展,第一就是方便接入第三方登录,第二嘛是为了别人方便接入我们,哈哈哈,以后中小企业,可以选择用微信登录,支付宝登录,还有PIP登录。。。
但行好事,莫问前程,我只管铺好了路,后面谁走都会很顺畅
springboot的版本是2.0.4.RELEASE,cloud的版本是对应的Finchley.SR1,基本上都是最新的。
Oauth2的出现就是为了解决信任问题,允许第三方客户端访问资源所有者的私有资源,在最开始接触这个协议时,总是转不过来角色,总把自己当做用户,其实在你去实现整个UAA时,你就是微信,就是Google了,角色转换了,整个认知就很舒服了。
但是跟gateway有啥关系呢?
公司所有服务都在网关下,不暴露在公网上,所以UAA也不例外
设计之初,UAA本身既是认证服务器,也是资源服务器,除此之外,如果再加资源服务器的话,需要在相应的微服务子项目上加一些代码。
不论出于什么考虑,在网关做鉴权都是合理合法的,但是看了好多官方的issue,gateway和oauth2还是存在一些问题,spring成员回复在spring5的webflux好像支持了,但是下面也被人回怼说还是一大顿bug。。。
框架的问题我解决不了,gateway的项目也不是我负责,所以只能退而求其次,只让gateway路由,其他不做任何事情。
但是!!
重点来了,在本地测试时,整个认证流程没有任何问题,上到测试环境,就卡在第一步,获取accessToken就是拿不到,一直返回401。。
经过多方排查,基本确定是网关拦截了一些信息,导致总是返回401
经过网关
curl --request POST \
--url 'https://localhost:9016/uaa/oauth/token?username=123456789&password=123456&grant_type=password&scope=USER_INFO&client_id=XnRFHdwI7KmOQ5nZ' \
--header 'Authorization: Basic WG5SRkhkd0k3S21PUTVuOkM2TzlLbTJORFg4VnRuWnl1ZEFnRjhFNkdTaU8zZWtG'
{
"timestamp": 1541216762332,
"status": 401,
"error": "Unauthorized",
"message": "Unauthorized",
"path": "/oauth/token"
}
复制代码
不经过网关
curl --request POST \
--url 'https://localhost:9000/oauth/token?username=123456789&password=123456&grant_type=password&scope=USER_INFO&client_id=XnRFHdwI7KmOQ5nZ' \
--header 'Authorization: Basic WG5SRkhkd0k3S21PUTVuOkM2TzlLbTJORFg4VnRuWnl1ZEFnRjhFNkdTaU8zZWtG'
{
"access_token": "cdb2f737-34fa-44ab-aa0d-0e7bbbf91d4c",
"token_type": "bearer",
"refresh_token": "6b059fa5-d93a-4991-8c1e-46d5b716bc6e",
"expires_in": 299,
"scope": "USER_INFO"
}
复制代码
除了端口号不一致之外,参数全部一致,可就是返回401!!
怎么回事呢??
答案揭晓:
gateway就算不搭配spring-cloud-oauth2,也会抹除一些敏感信息
例如:
header 'Authorization: Basic WG5SRkhkd0k3S21PUTVuOkM2TzlLbTJORFg4VnRuWnl1ZEFnRjhFNkdTaU8zZWtG'
复制代码
没法做basic认证,当然返回401了。
所以最后在gateway配置了一下,不要抹除敏感信息
zuul:
ignored-services: "*"
routes:
shop-user: /sys/user/**
sensitive-headers: