1.功能圖
之前我們的請求是直接會跳到一個請求登錄頁面的Controller,然後跳到登錄頁面,現在我們的需求是判斷一下請求的類型,然後跳轉到自己的Controller.,然後處理返回不同的信息。
現將之前的一些在demo-lilly裏面的配置沉澱到borwser包裏面,但是在打包的時候報找不到Filter,z所以在依賴中加上
要實現這樣的一個功能需要跳轉前判斷這個請求的類型,這裏需要HttpSessionRequestCache這個類拿到當前緩存的請求,
接到Html請求以後是否需要身份認證的這個判斷是Security做的,如果需要身份認證,他會做一個跳轉,根據你loginPage的配置來決定你跳到哪裏,但是在執行這個跳轉之前,Spring Security用HttpSessionRequestCache把當前的請求緩存到這個類裏面,所以我們可以根據這個類來拿當前請求的類型。
判斷之後利用這個類RedirectStrategy做跳轉,至於跳轉的請求需要從配置中拿。
下面介紹如何封裝系統配置
2.系統配置封裝
系統配置類我們寫到core包裏面,
springboot 訪問template資源必須經過控制器,如果想不經過控制器直接跳轉,需要將資源放到靜態文件夾下。但是thymeleaf放到靜態資源文件下有一個問題,就是頁面會出現中文亂碼,由於是靜態資源所以無法通過視圖解析器的配置去改變這一問題,就算解決了,thymeleaf的標籤在靜態資源下回全部失效,所以這種辦法不可取,我們需要採取第二種解決方式
首選先demo項目的自定義登錄配置頁面
封裝系統配置的第一個類
封裝系統配置的第二個類:
資源文件在:
使系統配置起作用:
注入即可使用:
需要注意的是需要加上Controller轉換到視圖,這個配置不能在starter包裏面去做轉換,因爲用戶可能需要在自定義頁面上顯示一些問題
3.登錄成功處理
默認情況下security登錄成功後會把請求轉到引發操作的請求上,那麼什麼時候需要自定義登錄成功的處理,比如說前端登錄後僅僅只想拿到用戶的信息去做處理,這個時候就需要自定義登錄成功的處理流程。
自定義登錄成功處理需要實現一個接口
然後加上這樣一個配置:
4.登錄失敗處理
實現AuthenticationFailureHandler接口
但是我們的目標是要做一個可重用的認證模塊,也就是說要包含返回json,和跳轉登錄的這兩種情況。
5.認證完成返回JSON或跳轉
實現的思路:首先security的默認的認證成功的處理類是SavedRequestAwareAuthenticationSuccessHandler,他一樣是實現了AuthenticationSuccessHandler接口,我們只需要繼承這個默認的,再判斷一下類型,實現自己的就行了。
兩種類型:
默認JSON處理
package org.lilly.browser.authentication;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.lilly.core.properties.LoginType;
import org.lilly.core.properties.SecurityProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* User: Mr.Wang
* Date: 2020/6/8
*/
@Component
public class LillyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private ObjectMapper objectMapper;
@Autowired
private SecurityProperties securityProperties;
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Authentication authentication) throws IOException,
ServletException {
logger.info("登錄成功");
if (LoginType.JSON.equals(securityProperties.getBrowser().getLoginType())) {
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.getWriter().write(objectMapper.writeValueAsString(authentication));
} else {
super.onAuthenticationSuccess(httpServletRequest, httpServletResponse, authentication);
}
}
}
demo項目配置:
測試:
首先我配置登錄的類型爲JSON類型或者不配置,訪問hello.html,會返回JSON
當我們配置登錄的類型後,訪問http://localhost:8080/preLogin.html
當然需要一個控制器來處理這個登錄的請求,登錄後會自動跳轉到登錄前的頁面
常見問題:
重定向次數太多,是因爲自定義請求的登錄頁面沒有去security放權
配置類無法注入使用,是因爲demo項目的包沒有掃描到