spring boot-使用Filter實現Header認證
阿新 • • 發佈:2019-02-17
前言
假設客戶端在http請求中,已經加入了Header的認證資訊,例如:
那麼服務端怎麼通過Filter,來驗證客戶端的token是否有效了?請接著往下看。HttpPost post = new HttpPost("http://localhost:8990/sendMail"); StringEntity entity = new StringEntity(json, "utf-8"); entity.setContentType("application/json"); post.setEntity(entity); // 設定驗證頭資訊 post.addHeader("token", "WEFGYHJIKLTY4RE6DF29HNBCFD13ER87");
一、實現自定義Filter
1、實現Filter介面
我們要自定義Filter,只需實現Filter介面即可
2、覆寫doFilter方法
根據業務邏輯,來覆寫doFilter方法
示例如下:
@Slf4j @Component @WebFilter(urlPatterns={"/sendMail/*"}, filterName="tokenAuthorFilter") public class TokenAuthorFilter implements Filter { @Autowired private AuthorizationRepository repository; @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest)request; response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); String token = req.getHeader("token"); Response res = new Response(); boolean isFilter = false; if (null == token || token.isEmpty()) { res.setSuccess(false); res.setErrorCode("403"); res.setErrorMessage("token沒有認證通過!原因為:客戶端請求引數中無token資訊"); } else { Authorization auth = repository.findByToken(token); if (null == auth) { res.setSuccess(false); res.setErrorCode("403"); res.setErrorMessage("token沒有認證通過!原因為:客戶端請求中認證的token資訊無效,請檢視申請流程中的正確token資訊"); }else if((auth.getStatus() == 0)){ res.setSuccess(false); res.setErrorCode("401"); res.setErrorMessage("該token目前已處於停用狀態,請聯絡郵件系統管理員確認!"); }else{ isFilter = true; res.setSuccess(true); } } if(!res.isSuccess()){ PrintWriter writer = null; OutputStreamWriter osw = null; try { osw = new OutputStreamWriter(response.getOutputStream() , "UTF-8"); writer = new PrintWriter(osw, true); String jsonStr = ObjectMapperInstance.getInstance().writeValueAsString(res); writer.write(jsonStr); writer.flush(); writer.close(); osw.close(); } catch (UnsupportedEncodingException e) { log.error("過濾器返回資訊失敗:" + e.getMessage(), e); } catch (IOException e) { log.error("過濾器返回資訊失敗:" + e.getMessage(), e); } finally { if (null != writer) { writer.close(); } if(null != osw){ osw.close(); } } return; } if(isFilter){ log.info("token filter過濾ok!"); chain.doFilter(request, response); } } @Override public void init(FilterConfig arg0) throws ServletException { } }
通過上面的幾步,就實現了一個自定義的Filter。
3、註冊Filter
接下來,需要註冊這個過濾器,spring boot提供了以下兩種註冊方式。
3.1 是用註解註冊
在Filter上新增如下註解即可
@Slf4j
@Component
@WebFilter(urlPatterns={"/sendMail/*"}, filterName="tokenAuthorFilter")
public class TokenAuthorFilter implements Filter {
@WebFilter註解的作用就是用來註冊Filter,通過這種方式註冊的Filter,需要在啟動類上加上@ServletComponentScan註解才能生效,如下:
@ServletComponentScan
public class MailserviceApplication {
public static void main(String[] args) {
SpringApplication.run(MailserviceApplication.class, args);
}
}
3.2 手動配置Filter
@Configuration
@Component
public class FilterConfig {
@Autowired
private TokenAuthorFilter filter;
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(filter);
List<String> urlPatterns = new ArrayList<String>();
urlPatterns.add("/sendMail/*");// 設定匹配的url
registrationBean.setUrlPatterns(urlPatterns);
return registrationBean;
}
}
上面兩種方式雖然使用上有些不一樣,但是本質都是一樣的,都會呼叫FilterRegistrationBean來進行註冊。
二、spring boot內建的Filter
為了方便我們的開發,spring boot內建了許多有用的Filter,我們可以根據業務的需求,選擇適合業務的Filter。
三、拓展
通過前面的N篇部落格,我們會發現spring boot處理Servlet,Listener,Filter的思路大致都是一樣,對應的註解分別為@WebServlet
、@WebListener
、@WebFilter
,對應的註冊Bean分別為
,無論哪種方式,都大大的簡化了我們的開發ServletRegistrationBean,
ServletListenerRegistrationBean
,FilterRegistrationBean