關於SpringSecurity的重定向到loginPage()頁面的一個坑
阿新 • • 發佈:2018-11-15
背景:
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
經過檢視原始碼,關鍵程式碼如下: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 不就完了嘛???