关于SpringSecurity的重定向到loginPage()页面的一个坑
背景:
SpringBoot+SpringSecurity搭建的一个web服务,注册到SpringEureka注册中心,通过SpringZuul进行统一网关访问
问题:
我们知道,当我要访问该web服务的一个请求 /test 且该请求需要用户认证,那么SpringSecurity会将请求302到通过 httpSecurity.formLogin().loginPage("/login") 设定的页面里。问题就出在这个302。
假如:SpringZuul配置了域名 http://www.zuul.test.com,然后该web服务器ip地址为 192.168.1.10 且该ip地址对公网不可见。那么当然我访问 http://www.zuul.test.com/test 的时候, SpringSecurity竟然将请求302到了 http://192.168.1.10:8080/login,但是我的 192.168.1.10 这台服务器对公网是不可见的啊?怎么可能访问的通?
经过查看源码,关键代码如下:org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint
protected String buildRedirectUrlToLoginPage(HttpServletRequest request,
HttpServletResponse response, AuthenticationException authException) {
String loginForm = determineUrlToUseForThisRequest(request, response,
authException);
if (UrlUtils.isAbsoluteUrl(loginForm)) {
return loginForm;
}
int serverPort = portResolver.getServerPort(request);
String scheme = request.getScheme();
RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
urlBuilder.setScheme(scheme);
urlBuilder.setServerName(request.getServerName());
urlBuilder.setPort(serverPort);
urlBuilder.setContextPath(request.getContextPath());
urlBuilder.setPathInfo(loginForm);
if (forceHttps && "http".equals(scheme)) {
Integer httpsPort = portMapper.lookupHttpsPort(Integer.valueOf(serverPort));
if (httpsPort != null) {
// Overwrite scheme and port in the redirect URL
urlBuilder.setScheme("https");
urlBuilder.setPort(httpsPort.intValue());
}
else {
logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port "
+ serverPort);
}
}
return urlBuilder.getUrl();
}请注意标红这段代码,我不明白为什么SpringSecurity要直接去拿 request.getServerName() !!!,难道不考虑servlet服务器前面可能还会有个网关的问题吗???你直接重定向到 /login 不就完了嘛???
暂无解决办法!!!
原文地址:https://www.cnblogs.com/LOVE0612/p/9962718.html