springSecurity之如何添加自定義過(guò)濾器
springSecurity 添加自定義過(guò)濾器
我們知道,springSecurity其實(shí)就是將過(guò)濾器和aop進(jìn)行整合。其實(shí)我們也可以添加自己的過(guò)濾器。
很簡(jiǎn)單,配置如下
<http use-expressions="false" entry-point-ref="loginEntryPoint"> <intercept-url pattern="/user.jsp" access="ROLE_USER,ROLE_ADMIN"/> <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN"/> <intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY"/> <form-login/> <custom-filter ref="myFilter" position="LAST"/> </http> <beans:bean id="myFilter" class="com.ezhiyang.springSecurity.MyFilter"/>
然后再來(lái)看看myFilter
public class MyFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("進(jìn)來(lái)了我自定義的過(guò)濾器了");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
System.out.println("自定義過(guò)濾器鏈銷(xiāo)毀了");
}
}
其實(shí)只要實(shí)現(xiàn)了javax.servlet.Filter就可以了,很low.
springSecurity 自定義認(rèn)證過(guò)濾器
繼承 Filter 基類(lèi) OncePerRequestFilter 保證每個(gè)請(qǐng)求轉(zhuǎn)發(fā)執(zhí)行一次
public class MyAuthenticationProcessingFilter extends OncePerRequestFilter {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filterChain.doFilter(requestWrapper, response);
}
出現(xiàn)的問(wèn)題
在 filter 中消費(fèi)了 Request 中的 InputStream 導(dǎo)致后續(xù)的過(guò)濾器中無(wú)法調(diào)用 Request
解決方法
定義一個(gè) HttpServletRequestWrapper 類(lèi),將輸入流字節(jié)數(shù)據(jù)讀取出來(lái),以供使用,重新 getInputStream() 方法,將輸入流字節(jié)數(shù)組重新封裝成 ServletInputStream 輸入流即可,注意字符編碼
ServletRequestWrapper.java
public class ServletRequestWrapper extends HttpServletRequestWrapper {
private byte[] body;
private String requestParam;
/**
* Constructs a request object wrapping the given request.
* @Description: 將 request 中的流信息讀取出來(lái)供外部使用,將流緩存起來(lái),傳到下一個(gè) filter 中
* @param request The request to wrap
* @throws IllegalArgumentException if the request is null
*/
public ServletRequestWrapper(HttpServletRequest request) {
super(request);
requestParam = HttpUtil.getBodyString(request);
body = requestParam.getBytes(Charset.forName("utf-8"));
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getRequest().getInputStream(), Charset.forName("UTF-8")));
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new CustomServletInputStream();
}
private class CustomServletInputStream extends ServletInputStream {
private ByteArrayInputStream inputStream = new ByteArrayInputStream(body);
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
@Override
public int read() throws IOException {
return inputStream.read();
}
}
public String getRequestParam() {
return requestParam;
}
}
HttpUtil.java
public class HttpUtil {
public static String getBodyString(ServletRequest request) {
BufferedReader bufferedReader = null;
InputStream inputStream = null;
StringBuilder sb = new StringBuilder("");
try {
inputStream = request.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("utf-8")));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringSecurity的安全過(guò)濾器鏈功能詳解
- SpringSecurity中內(nèi)置過(guò)濾器的使用小結(jié)
- springSecurity自定義登錄接口和JWT認(rèn)證過(guò)濾器的流程
- SpringSecurity中的Filter Chain(過(guò)濾器鏈)
- idea如何debug看springsecurity的過(guò)濾器順序
- SpringSecurity request過(guò)濾問(wèn)題示例小結(jié)
- SpringSecurity定義多個(gè)過(guò)濾器鏈的操作代碼
- SpringSecurity學(xué)習(xí)之自定義過(guò)濾器的實(shí)現(xiàn)代碼
- springSecurity過(guò)濾web請(qǐng)求的項(xiàng)目實(shí)踐
相關(guān)文章
java正則表達(dá)式如何獲取xml文件中指定節(jié)點(diǎn)的值
這篇文章主要介紹了java正則表達(dá)式如何獲取xml文件中指定節(jié)點(diǎn)的值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
spring boot啟動(dòng)出現(xiàn)Unable to start ServletWe
在使用SpringBoot時(shí),啟動(dòng)報(bào)錯(cuò)可能源于多種原因,錯(cuò)誤提示為缺少ServletWebServerFactory bean,初步分析可能是缺少spring-boot-starter-web依賴或@EnableAutoConfiguration注解,感興趣的可以了解一下2024-10-10
SpringBoot處理請(qǐng)求參數(shù)中包含特殊符號(hào)
今天寫(xiě)代碼遇到了一個(gè)問(wèn)題,請(qǐng)求參數(shù)是個(gè)路徑“D:/ExcelFile”,本文就詳細(xì)的介紹一下該錯(cuò)誤的解決方法,感興趣的可以了解一下2021-06-06
java中的BlockingQueue(阻塞隊(duì)列)解析
這篇文章主要介紹了java中的BlockingQueue阻塞隊(duì)列解析,阻塞隊(duì)列是一個(gè)支持兩個(gè)附加操作的隊(duì)列,這兩個(gè)附加的操作是,在隊(duì)列為空時(shí),獲取元素的線程會(huì)等待隊(duì)列變?yōu)榉强?需要的朋友可以參考下2023-12-12
mybatis自定義類(lèi)型處理器的實(shí)現(xiàn)
在MyBatis使用中,有時(shí)需要對(duì)特定數(shù)據(jù)類(lèi)型進(jìn)行定制處理,自定義類(lèi)型處理器(TypeHandler)可以實(shí)現(xiàn)這一需求,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-10-10
Java Lock鎖多線程中實(shí)現(xiàn)流水線任務(wù)
這篇文章主要介紹了Java Lock鎖多線程中實(shí)現(xiàn)流水線任務(wù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05

