springSecurity之如何添加自定義過濾器
springSecurity 添加自定義過濾器
我們知道,springSecurity其實(shí)就是將過濾器和aop進(jìn)行整合。其實(shí)我們也可以添加自己的過濾器。
很簡單,配置如下
<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"/>
然后再來看看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)來了我自定義的過濾器了"); filterChain.doFilter(servletRequest,servletResponse); } @Override public void destroy() { System.out.println("自定義過濾器鏈銷毀了"); } }
其實(shí)只要實(shí)現(xiàn)了javax.servlet.Filter就可以了,很low.
springSecurity 自定義認(rèn)證過濾器
繼承 Filter 基類 OncePerRequestFilter 保證每個(gè)請求轉(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)的問題
在 filter 中消費(fèi)了 Request 中的 InputStream 導(dǎo)致后續(xù)的過濾器中無法調(diào)用 Request
解決方法
定義一個(gè) HttpServletRequestWrapper 類,將輸入流字節(jié)數(shù)據(jù)讀取出來,以供使用,重新 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 中的流信息讀取出來供外部使用,將流緩存起來,傳到下一個(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è)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java中生成任意之間數(shù)的隨機(jī)數(shù)詳解
這篇文章主要介紹了java中生成任意之間數(shù)的隨機(jī)數(shù)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09SpringBoot處理JSON數(shù)據(jù)方法詳解
這篇文章主要介紹了SpringBoot整合Web開發(fā)中Json數(shù)據(jù)處理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-10-10Java?zxing實(shí)現(xiàn)生成并解析二維碼與條形碼
這篇文章主要為大家詳細(xì)介紹了Java如何通過zxing實(shí)現(xiàn)生成并解析二維碼與條形碼,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2024-11-11SpringBoot中將@Bean方法解析為BeanDefinition詳解
這篇文章主要介紹了SpringBoot中將@Bean方法解析為BeanDefinition詳解,得到的BeanDefinition是ConfigurationClassBeanDefinition類型,會為BeanDefinition設(shè)置factoryMethodName,這意味著當(dāng)實(shí)例化這個(gè)bean的時(shí)候?qū)⒉捎霉S方法,需要的朋友可以參考下2023-12-12Java中消息隊(duì)列任務(wù)的平滑關(guān)閉詳解
對于消息隊(duì)列的監(jiān)聽,我們一般使用Java寫一個(gè)獨(dú)立的程序,在Linux服務(wù)器上運(yùn)行。程序啟動后,通過消息隊(duì)列客戶端接收消息,放入一個(gè)線程池進(jìn)行異步處理,并發(fā)的快速處理。這篇文章主要給大家介紹了關(guān)于Java中消息隊(duì)列任務(wù)的平滑關(guān)閉的相關(guān)資料,需要的朋友可以參考下。2017-11-11