前後端分離專案shiro驗證
阿新 • • 發佈:2019-02-13
公司新專案,要做前後端分離專案,在開發過程中,需要使用shiro來做會話管理。由於是前後端分離 ,前端是通過ajax請求後端地址,後端程式沒辦法將sessionId寫到請求瀏覽器cookie中,所以需要重新設想方案。
通過對shiro專案研究發現,shiro框架在每次請求的cookie中,都帶有一對這樣的引數
JSESSIONID=476dae2a-4cf7-49f9-a684-3a4736d2b1b6
然後,我們使用httpclinet 帶上該cookie模擬請求,發現可以通過驗證,拿到資料。 然後通過除錯發現,這個JSESSIONID所儲存的就是回話sessionId。所以我們設想,在登入的時候,給前端返回改欄位,讓前端將這個欄位寫入到cookie中,這樣每次請求自動帶上了該cookie,從而實現會話驗證。
shiro的配置檔案如下:
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <property name="loginUrl" value="/api/user/login"/> <property name="successUrl" value="/"/> <property name="unauthorizedUrl"value="/page/401"/> <property name="filters"> <util:map> <entry key="login" value-ref="loginFilter"></entry> </util:map> </property> <property name="filterChainDefinitions"> <value> <!-- 登入頁允許訪問 --> /api/user/login = anon <!-- 其他資源需要認證 -->/** = login </value> </property> </bean>
對於登入介面不做許可權控制,對於其他介面增加了一個攔截器的配置。
攔截器的程式碼如下
public class LoginFilter extends AccessControlFilter { @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { Subject subject = SecurityUtils.getSubject(); if(null != subject && subject.isAuthenticated()){ return Boolean.TRUE; } /* if (WebUtils.isAjax(request)) {// ajax請求*/ Map<String,String> resultMap = new HashMap<String, String>(5); resultMap.put("code", MessageCode.USER_NOT_LOGIN[0]); resultMap.put("status", Constant.STATUS_FAIL); resultMap.put("msg", MessageCode.USER_NOT_LOGIN[1]);//當前使用者沒有登入! WebUtils.out((HttpServletRequest) request,(HttpServletResponse) response, resultMap); /*}*/ return Boolean.FALSE ; } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { //儲存Request和Response 到登入後的連結 /* saveRequestAndRedirectToLogin(request, response);*/ return Boolean.FALSE ; } }
攔截器對於所有未登入,或者session過期的使用者直接返回json攔截。