1. 程式人生 > >關於SpringSecurity的重定向到loginPage()頁面的一個坑

關於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 不就完了嘛???

 

暫無解決辦法!!!