最近在给 Docs4dev 添加用户评论功能时,使用了 Github
提供的 OAuth2
认证来进行用户身份认证,在本地开发环境中一切正常,但是一放到服务器就会认证失败,查看日志后发现 OAuth2
的 redirectUri
参数不匹配,在添加了相关日志后,发现 Spring Boot
是通过 UrlUtils.buildFullRequestUrl(request)
从 HttpServletRequest
中获取的 redirectUri
:
OAuth2LoginAuthenticationFilter
String redirectUri = UriComponentsBuilder.fromHttpUrl(UrlUtils.buildFullRequestUrl(request))
.replaceQuery(null)
.build()
.toUriString();
但是,服务器上配置了 nginx
作为反向代理服务器,这就导致了在 Spring
中,无法正确获取 scheme
和 host
,这就导致了 redirectUri
无法正确匹配从而认证失败。
找到了问题,解决它就很简单了,我们只需要对 nginx
和 tomcat
进行简单的设置就行了。
Nginx
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
Tomcat
<Engine >
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto"
protocolHeaderHttpsValue="https"/>
Engine >
如果你使用的是 Spring Boot
内嵌的 Tomcat
,可以在 application.yml
中进行设置:
server:
tomcat:
remote-ip-header: "X-Forwarded-For"
protocol-header: "X-Forwarded-Proto"
protocol-header-https-value: "https"
以上的设置只是为了让 Tomcat
能获取正确的 host
以及 schme
,这样,Spring
就能获取正确的 redirectUri
参数了。