shiro自定義過濾器
阿新 • • 發佈:2018-11-21
就是自定義過濾規則 一些特殊的請求路徑 需要進過自定義的過濾器 在自定義的過濾器中 認證規則是自己定的
spring檔案:
我們自定義了一個phoneFilter 在過濾器鏈中匹配到時 就會到該過濾器中執行
在自定義的過濾器中 有兩個方法會先執行isAccessAllowed()方法 這個方法中如果放回false才會執行onAccessDenied() 如果放回true的話程式就會無條件執行 我們一般在isAccessAllowed()方法中執行授權 方法 subject.isPermitted(caozuo) 這個方法會執行授權方法執行成功的話放回true 執行失敗的話放回false 執行onAccessDenied()方法
spring檔案:
<!-- 引入資料來源 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 配置資料庫連線池 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="maxActive" value="10" /> <property name="maxIdle" value="5" /> </bean> <!-- 自定義的shiro 過濾器 --> <bean id="phoneFilter" class="cn.neusoft.filter.UserPhoneFilter"> <property name="userdao" ref="userDao"></property> </bean> <!-- Shiro的過濾器工廠BEAN : 間接地載入9個內建過濾器 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 安全管理器 :Shiro的核心元件,相當於大腦 --> <property name="securityManager" ref="securityManager" /> <!-- 認證相關: 指定登陸頁面,當用戶未登陸時訪問資源,則自動跳轉到此頁面 --> <property name="loginUrl" value="/login.jsp" /> <!-- 授權相關:指定錯誤頁面,當用戶登陸後訪問沒有許可權的資源時,自動跳轉到此頁面 --> <property name="unauthorizedUrl" value="/error.html" /> <property name="filters"> <map> <entry key="phone" value-ref="phoneFilter" /> </map> </property> <!-- 過濾器鏈定義:指定頁面的訪問規則 --> <property name="filterChainDefinitions"> <value> /userphone/login.action =anon /user/login.action = anon /login.jsp =anon /user/all.action = authc <!-- 新增的許可權 --> /user/goadd.action =perms["add"] /user/add.action =perms["add"] <!-- 修改的許可權 --> /user/goedit.action =perms["update"] /user/update.action =perms["update"] <!-- 刪除的許可權 --> /user/delete.action =perms["delete"] /userphone/* =phone /userphone/select.action =authc /userphone/add.action=perms["add"] /userphone/update.action =perms["update"] /userphone/delete.action =perms["delete"] /*.html = authc /*.action = authc /* = authc </value> </property> </bean> <!-- 安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="userRealm"></property> </bean> <!-- 自定義Realm --> <bean id="userRealm" class="cn.neusoft.realm.UserRealm"> <property name="userService" ref="userService"></property> <property name="user" ref="user"></property> </bean> </beans>
我們自定義了一個phoneFilter 在過濾器鏈中匹配到時 就會到該過濾器中執行
public class UserPhoneFilter extends AuthenticationFilter{ private UserDao userdao; public void setUserdao(UserDao userdao) { this.userdao = userdao; } @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { response.setCharacterEncoding("UTF-8"); response.setContentType("application/json; charset=utf-8"); String sessionid = request.getParameter("sessionid"); //1.沒有sessionid 2.有sessionid 資料庫沒資料 3.有sessionid 資料庫有資料 沒有使用者 4.有使用者 沒許可權執行 //判斷sessionid是否存在 如不存在返回路徑錯誤 if(sessionid.equals("")){ Map map = jsonReturn(false,"沒有登入記錄,請重新登陸"); try { response.getWriter().print(JSON.toJSONString(map)); return false; } catch (IOException e) { e.printStackTrace(); } } PhoneId phoneId = userdao.getsession(sessionid); if(phoneId==null){ //如果sessionid存在 資料庫沒查到 返回身份過期 Map map = jsonReturn(false,"登入資訊過期,請重新登入"); try { response.getWriter().print(JSON.toJSONString(map)); return false; } catch (IOException e) { e.printStackTrace(); } } //資料庫中根據sessionid取登陸物件 //不為空 從資料庫查到當前登陸物件 User user = userdao.selectone(phoneId.getUid().toString()); if(user==null){ //通過使用者ID查不到 可能已刪除 Map map = jsonReturn(false,"使用者資訊有問題,請重新登陸"); try { response.getWriter().print(JSON.toJSONString(map)); return false; } catch (IOException e) { e.printStackTrace(); } } //------------------------------------------------------------------------------ Subject subject = getSubject(request, response); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(),user.getPassword()); subject.login(token); //------------------------------------------------------------------------------ String path = getPathWithinApplication(request); String string = path.substring(11, path.length()); String caozuo = string.substring(0, string.indexOf(".")); //------------------------------------------------------------------------------ System.out.println(caozuo); System.out.println("第二過濾器!!"); //物件也從資料庫查到了 出錯的唯一可能就是當前物件沒有許可權執行 if(subject.isPermitted(caozuo)){ return true; }else{ Map map = jsonReturn(false,"該使用者沒有許可權執行當前資源"); try { response.getWriter().print(JSON.toJSONString(map)); } catch (IOException e) { } return false; } } //isAccessAllowed 方法返回false 執行 @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse reponse) throws Exception { System.out.println("沒成功!!!!!!!!!"); return false; } public Map jsonReturn(boolean type,String message){ Map map = new HashMap<Boolean, String>(); map.put("success", type); map.put("value", message); return map; } }
在自定義的過濾器中 有兩個方法會先執行isAccessAllowed()方法 這個方法中如果放回false才會執行onAccessDenied() 如果放回true的話程式就會無條件執行 我們一般在isAccessAllowed()方法中執行授權 方法 subject.isPermitted(caozuo) 這個方法會執行授權方法執行成功的話放回true 執行失敗的話放回false 執行onAccessDenied()方法