日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

shiro学习(19): 拦截器

發布時間:2023/12/10 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 shiro学习(19): 拦截器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 攔截器介紹

?? Shiro使用了與Servlet一樣的Filter接口進行擴展;所以如果對Filter不熟悉可以參考《Servlet3.1規范》http://www.iteye.com/blogs/subjects/Servlet-3-1了解Filter的工作原理。首先下圖是Shiro攔截器的基礎類圖:

1、NameableFilter
??? NameableFilter給Filter起個名字,如果沒有設置默認就是FilterName;還記得之前的如authc嗎?當我們組裝攔截器鏈時會根據這個名字找到相應的攔截器實例;
2、OncePerRequestFilter
??? OncePerRequestFilter用于防止多次執行Filter的;也就是說一次請求只會走一次攔截器鏈;另外提供enabled屬性,表示是否開啟該攔截器實例,默認enabled=true表示開啟,如果不想讓某個攔截器工作,可以設置為false即可。
3、ShiroFilter
??? ShiroFilter是整個Shiro的入口點,用于攔截需要安全控制的請求進行處理,這個之前已經用過了。
4、AdviceFilter
??? AdviceFilter提供了AOP風格的支持,類似于SpringMVC中的Interceptor

?

[java] view plain copy print?

  • boolean?preHandle(ServletRequest?request,?ServletResponse?response)?throws?Exception????
  • void?postHandle(ServletRequest?request,?ServletResponse?response)?throws?Exception????
  • void?afterCompletion(ServletRequest?request,?ServletResponse?response,?Exception?exception)?throws?Exception;????
  • ??? preHandler:類似于AOP中的前置增強;在攔截器鏈執行之前執行;如果返回true則繼續攔截器鏈;否則中斷后續的攔截器鏈的執行直接返回;進行預處理(如基于表單的身份驗證、授權)
    ??? postHandle:類似于AOP中的后置返回增強;在攔截器鏈執行完成后執行;進行后處理(如記錄執行時間之類的);
    ??? afterCompletion:類似于AOP中的后置最終增強;即不管有沒有異常都會執行;可以進行清理資源(如接觸Subject與線程的綁定之類的);

    ?

    5、PathMatchingFilter
    ??? PathMatchingFilter提供了基于Ant風格的請求路徑匹配功能及攔截器參數解析的功能,如“roles[admin,user]”自動根據“,”分割解析到一個路徑參數配置并綁定到相應的路徑:

    [java] view plain copy print?

  • boolean?pathsMatch(String?path,?ServletRequest?request)????
  • boolean?onPreHandle(ServletRequest?request,?ServletResponse?response,?Object?mappedValue)?throws?Exception????
  • ??? pathsMatch:該方法用于path與請求路徑進行匹配的方法;如果匹配返回true;
    ??? onPreHandle:在preHandle中,當pathsMatch匹配一個路徑后,會調用opPreHandler方法并將路徑綁定參數配置傳給mappedValue;然后可以在這個方法中進行一些驗證(如角色授權),如果驗證失敗可以返回false中斷流程;默認返回true;也就是說子類可以只實現onPreHandle即可,無須實現preHandle。如果沒有path與請求路徑匹配,默認是通過的(即preHandle返回true)。

    6、AccessControlFilter
    ??? AccessControlFilter提供了訪問控制的基礎功能;比如是否允許訪問/當訪問拒絕時如何處理等:

    ?

    [java] view plain copy print?

  • abstract?boolean?isAccessAllowed(ServletRequest?request,?ServletResponse?response,?Object?mappedValue)?throws?Exception;????
  • boolean?onAccessDenied(ServletRequest?request,?ServletResponse?response,?Object?mappedValue)?throws?Exception;????
  • abstract?boolean?onAccessDenied(ServletRequest?request,?ServletResponse?response)?throws?Exception;????
  • ??? isAccessAllowed:表示是否允許訪問;mappedValue就是[urls]配置中攔截器參數部分,如果允許訪問返回true,否則false;
    ??? onAccessDenied:表示當訪問拒絕時是否已經處理了;如果返回true表示需要繼續處理;如果返回false表示該攔截器實例已經處理了,將直接返回即可。

    ?

    onPreHandle會自動調用這兩個方法決定是否繼續處理:

    [java] view plain copy print?

  • boolean?onPreHandle(ServletRequest?request,?ServletResponse?response,?Object?mappedValue)?throws?Exception?{????
  • ????return?isAccessAllowed(request,?response,?mappedValue)?||?onAccessDenied(request,?response,?mappedValue);????
  • }???
  • 另外AccessControlFilter還提供了如下方法用于處理如登錄成功后/重定向到上一個請求:

    [java] view plain copy print?

  • void?setLoginUrl(String?loginUrl)?//身份驗證時使用,默認/login.jsp????
  • String?getLoginUrl()????
  • Subject?getSubject(ServletRequest?request,?ServletResponse?response)?//獲取Subject實例????
  • boolean?isLoginRequest(ServletRequest?request,?ServletResponse?response)//當前請求是否是登錄請求????
  • void?saveRequestAndRedirectToLogin(ServletRequest?request,?ServletResponse?response)?throws?IOException?//將當前請求保存起來并重定向到登錄頁面????
  • void?saveRequest(ServletRequest?request)?//將請求保存起來,如登錄成功后再重定向回該請求????
  • void?redirectToLogin(ServletRequest?request,?ServletResponse?response)?//重定向到登錄頁面?????
  • ??? 比如基于表單的身份驗證就需要使用這些功能。
    ??? 到此基本的攔截器就完事了,如果我們想進行訪問訪問的控制就可以繼承AccessControlFilter;如果我們要添加一些通用數據我們可以直接繼承PathMatchingFilter。

    ?

    2 攔截器鏈

    ??? Shiro對Servlet容器的FilterChain進行了代理,即ShiroFilter在繼續Servlet容器的Filter鏈的執行之前,通過ProxiedFilterChain對Servlet容器的FilterChain進行了代理;即先走Shiro自己的Filter體系,然后才會委托給Servlet容器的FilterChain進行Servlet容器級別的Filter鏈執行;
    ??? Shiro的ProxiedFilterChain執行流程:1、先執行Shiro自己的Filter鏈;2、再執行Servlet容器的Filter鏈(即原始的Filter)。
    ??? 而ProxiedFilterChain是通過FilterChainResolver根據配置文件中[urls]部分是否與請求的URL是否匹配解析得到的。

    [java] view plain copy print?

  • FilterChain?getChain(ServletRequest?request,?ServletResponse?response,?FilterChain?originalChain);????
  • ??? 即傳入原始的chain得到一個代理的chain。
    ??? Shiro內部提供了一個路徑匹配的FilterChainResolver實現:PathMatchingFilterChainResolver,其根據[urls]中配置的url模式(默認Ant風格)=攔截器鏈和請求的url是否匹配來解析得到配置的攔截器鏈的;而PathMatchingFilterChainResolver內部通過FilterChainManager維護著攔截器鏈,比如DefaultFilterChainManager實現維護著url模式與攔截器鏈的關系。因此我們可以通過FilterChainManager進行動態動態增加url模式與攔截器鏈的關系。
    ??? DefaultFilterChainManager會默認添加org.apache.shiro.web.filter.mgt.DefaultFilter中聲明的攔截器:

    [java] view plain copy print?

  • public?enum?DefaultFilter?{????
  • ????anon(AnonymousFilter.class),????
  • ????authc(FormAuthenticationFilter.class),????
  • ????authcBasic(BasicHttpAuthenticationFilter.class),????
  • ????logout(LogoutFilter.class),????
  • ????noSessionCreation(NoSessionCreationFilter.class),????
  • ????perms(PermissionsAuthorizationFilter.class),????
  • ????port(PortFilter.class),????
  • ????rest(HttpMethodPermissionFilter.class),????
  • ????roles(RolesAuthorizationFilter.class),????
  • ????ssl(SslFilter.class),????
  • ????user(UserFilter.class);????
  • }?????
  • ??? 如果要注冊自定義攔截器,IniSecurityManagerFactory/WebIniSecurityManagerFactory在啟動時會自動掃描ini配置文件中的[filters]/[main]部分并注冊這些攔截器到DefaultFilterChainManager;且創建相應的url模式與其攔截器關系鏈。如果使用Spring后續章節會介紹如果注冊自定義攔截器。
    ??? 如果想自定義FilterChainResolver,可以通過實現WebEnvironment接口完成:

    [java] view plain copy print?

  • public?class?MyIniWebEnvironment?extends?IniWebEnvironment?{????
  • ????@Override????
  • ????protected?FilterChainResolver?createFilterChainResolver()?{????
  • ????????//在此處擴展自己的FilterChainResolver????
  • ????????return?super.createFilterChainResolver();????
  • ????}????
  • }?????
  • ??? FilterChain之間的關系。如果想動態實現url-攔截器的注冊,就可以通過實現此處的FilterChainResolver來完成,比如:

    [java] view plain copy print?

  • //1、創建FilterChainResolver????
  • PathMatchingFilterChainResolver?filterChainResolver?=????
  • ????????new?PathMatchingFilterChainResolver();????
  • //2、創建FilterChainManager????
  • DefaultFilterChainManager?filterChainManager?=?new?DefaultFilterChainManager();????
  • //3、注冊Filter????
  • for(DefaultFilter?filter?:?DefaultFilter.values())?{????
  • ????filterChainManager.addFilter(????
  • ????????filter.name(),?(Filter)?ClassUtils.newInstance(filter.getFilterClass()));????
  • }????
  • //4、注冊URL-Filter的映射關系????
  • filterChainManager.addToChain("/login.jsp",?"authc");????
  • filterChainManager.addToChain("/unauthorized.jsp",?"anon");????
  • filterChainManager.addToChain("/**",?"authc");????
  • filterChainManager.addToChain("/**",?"roles",?"admin");????
  • ????
  • //5、設置Filter的屬性????
  • FormAuthenticationFilter?authcFilter?=????
  • ?????????(FormAuthenticationFilter)filterChainManager.getFilter("authc");????
  • authcFilter.setLoginUrl("/login.jsp");????
  • RolesAuthorizationFilter?rolesFilter?=????
  • ??????????(RolesAuthorizationFilter)filterChainManager.getFilter("roles");????
  • rolesFilter.setUnauthorizedUrl("/unauthorized.jsp");????
  • ????
  • filterChainResolver.setFilterChainManager(filterChainManager);????
  • return?filterChainResolver;?????
  • ??? 此處自己去實現注冊filter,及url模式與filter之間的映射關系。可以通過定制FilterChainResolver或FilterChainManager來完成諸如動態URL匹配的實現。

    ?

    ???? 然后再web.xml中進行如下配置Environment:??

    [html] view plain copy print?

  • <context-param>????
  • <param-name>shiroEnvironmentClass</param-name>?<param-value>com.github.zhangkaitao.shiro.chapter8.web.env.MyIniWebEnvironment</param-value>????
  • </context-param>?????
  • 3 自定義攔截器

    ??? 通過自定義自己的攔截器可以擴展一些功能,諸如動態url-角色/權限訪問控制的實現、根據Subject身份信息獲取用戶信息綁定到Request(即設置通用數據)、驗證碼驗證、在線用戶信息的保存等等,因為其本質就是一個Filter;所以Filter能做的它就能做。
    ??? 對于Filter的介紹請參考《Servlet規范》中的Filter部分:http://www.iteye.com/blogs/subjects/Servlet-3-1。

    1、擴展OncePerRequestFilter
    ??? OncePerRequestFilter保證一次請求只調用一次doFilterInternal,即如內部的forward不會再多執行一次doFilterInternal:

    [java] view plain copy print?

  • public?class?MyOncePerRequestFilter?extends?OncePerRequestFilter?{????
  • ????@Override????
  • ????protected?void?doFilterInternal(ServletRequest?request,?ServletResponse?response,?FilterChain?chain)?throws?ServletException,?IOException?{????
  • ????????System.out.println("=========once?per?request?filter");????
  • ????????chain.doFilter(request,?response);????
  • ????}????
  • }?????
  • 然后再shiro.ini配置文件中:

    [java] view plain copy print?

  • [main]????
  • myFilter1=com.github.zhangkaitao.shiro.chapter8.web.filter.MyOncePerRequestFilter????
  • #[filters]????
  • #myFilter1=com.github.zhangkaitao.shiro.chapter8.web.filter.MyOncePerRequestFilter????
  • [urls]????
  • /**=myFilter1????
  • ??? Filter可以在[main]或[filters]部分注冊,然后在[urls]部分配置url與filter的映射關系即可。
    2、擴展AdviceFilter
    ??? AdviceFilter提供了AOP的功能,其實現和SpringMVC中的Interceptor思想一樣:具體可參考我的SpringMVC教程中的處理器攔截器部分:http://www.iteye.com/blogs/subjects/kaitao-springmvc

    [java] view plain copy print?

  • public?class?MyAdviceFilter?extends?AdviceFilter?{????
  • ????@Override????
  • ????protected?boolean?preHandle(ServletRequest?request,?ServletResponse?response)?throws?Exception?{????
  • ????????System.out.println("====預處理/前置處理");????
  • ????????return?true;//返回false將中斷后續攔截器鏈的執行????
  • ????}????
  • ????@Override????
  • ????protected?void?postHandle(ServletRequest?request,?ServletResponse?response)?throws?Exception?{????
  • ????????System.out.println("====后處理/后置返回處理");????
  • ????}????
  • ????@Override????
  • ????public?void?afterCompletion(ServletRequest?request,?ServletResponse?response,?Exception?exception)?throws?Exception?{????
  • ????????System.out.println("====完成處理/后置最終處理");????
  • ????}????
  • }?????
  • ??? preHandle:進行請求的預處理,然后根據返回值決定是否繼續處理(true:繼續過濾器鏈);可以通過它實現權限控制;
    ??? postHandle:執行完攔截器鏈之后正常返回后執行;
    ??? afterCompletion:不管最后有沒有異常,afterCompletion都會執行,完成如清理資源功能。

    ?然后在shiro.ini中進行如下配置:

    ?

    [java] view plain copy print?

  • [filters]????
  • myFilter1=com.github.zhangkaitao.shiro.chapter8.web.filter.MyOncePerRequestFilter????
  • myFilter2=com.github.zhangkaitao.shiro.chapter8.web.filter.MyAdviceFilter????
  • [urls]????
  • /**=myFilter1,myFilter2?????
  • ?

    ??? 該過濾器的具體使用可參考我的SpringMVC教程中的處理器攔截器部分。

    ?3、PathMatchingFilter
    ??? PathMatchingFilter繼承了AdviceFilter,提供了url模式過濾的功能,如果需要對指定的請求進行處理,可以擴展PathMatchingFilter:

    ?

    [java] view plain copy print?

  • public?class?MyPathMatchingFilter?extends?PathMatchingFilter?{????
  • ????@Override????
  • ????protected?boolean?onPreHandle(ServletRequest?request,?ServletResponse?response,?Object?mappedValue)?throws?Exception?{????
  • ???????System.out.println("url?matches,config?is?"?+?Arrays.toString((String[])mappedValue));????
  • ???????return?true;????
  • ????}????
  • }?????
  • ??? preHandle:會進行url模式與請求url進行匹配,如果匹配會調用onPreHandle;如果沒有配置url模式/沒有url模式匹配,默認直接返回true;
    ??? onPreHandle:如果url模式與請求url匹配,那么會執行onPreHandle,并把該攔截器配置的參數傳入。默認什么不處理直接返回true。
    然后在shiro.ini中進行如下配置:

    [html] view plain copy print?

  • [filters]????
  • myFilter3=com.github.zhangkaitao.shiro.chapter8.web.filter.MyPathMatchingFilter????
  • [urls]????
  • /**=?myFilter3[config]?????
  • ???? /**就是注冊給PathMatchingFilter的url模式,config就是攔截器的配置參數,多個之間逗號分隔,onPreHandle使用mappedValue接收參數值。
    4、擴展AccessControlFilter
    ??? AccessControlFilter繼承了PathMatchingFilter,并擴展了了兩個方法:

    [java] view plain copy print?

  • public?boolean?onPreHandle(ServletRequest?request,?ServletResponse?response,?Object?mappedValue)?throws?Exception?{????
  • ????return?isAccessAllowed(request,?response,?mappedValue)????
  • ?????||?onAccessDenied(request,?response,?mappedValue);????
  • }?????
  • ??? isAccessAllowed:即是否允許訪問,返回true表示允許;
    ??? onAccessDenied:表示訪問拒絕時是否自己處理,如果返回true表示自己不處理且繼續攔截器鏈執行,返回false表示自己已經處理了(比如重定向到另一個頁面)。

    [java] view plain copy print?

  • public?class?MyAccessControlFilter?extends?AccessControlFilter?{????
  • ????protected?boolean?isAccessAllowed(ServletRequest?request,?ServletResponse?response,?Object?mappedValue)?throws?Exception?{????
  • ????????System.out.println("access?allowed");????
  • ????????return?true;????
  • ????}????
  • ????protected?boolean?onAccessDenied(ServletRequest?request,?ServletResponse?response)?throws?Exception?{????
  • ????????System.out.println("訪問拒絕也不自己處理,繼續攔截器鏈的執行");????
  • ????????return?true;????
  • ????}????
  • }?????
  • 然后在shiro.ini中進行如下配置:

    [java] view plain copy print?

  • [filters]????
  • myFilter4=com.github.zhangkaitao.shiro.chapter8.web.filter.MyAccessControlFilter????
  • [urls]????
  • /**=myFilter4????
  • 5、基于表單登錄攔截器
    ??? 之前我們已經使用過Shiro內置的基于表單登錄的攔截器了,此處自己做一個類似的基于表單登錄的攔截器。

    [java] view plain copy print?

  • public?class?FormLoginFilter?extends?PathMatchingFilter?{????
  • ????private?String?loginUrl?=?"/login.jsp";????
  • ????private?String?successUrl?=?"/";????
  • ????@Override????
  • ????protected?boolean?onPreHandle(ServletRequest?request,?ServletResponse?response,?Object?mappedValue)?throws?Exception?{????
  • ????????if(SecurityUtils.getSubject().isAuthenticated())?{????
  • ????????????return?true;//已經登錄過????
  • ????????}????
  • ????????HttpServletRequest?req?=?(HttpServletRequest)?request;????
  • ????????HttpServletResponse?resp?=?(HttpServletResponse)?response;????
  • ????????if(isLoginRequest(req))?{????
  • ????????????if("post".equalsIgnoreCase(req.getMethod()))?{//form表單提交????
  • ????????????????boolean?loginSuccess?=?login(req);?//登錄????
  • ????????????????if(loginSuccess)?{????
  • ????????????????????return?redirectToSuccessUrl(req,?resp);????
  • ????????????????}????
  • ????????????}????
  • ????????????return?true;//繼續過濾器鏈????
  • ????????}?else?{//保存當前地址并重定向到登錄界面????
  • ????????????saveRequestAndRedirectToLogin(req,?resp);????
  • ????????????return?false;????
  • ????????}????
  • ????}????
  • ????private?boolean?redirectToSuccessUrl(HttpServletRequest?req,?HttpServletResponse?resp)?throws?IOException?{????
  • ????????WebUtils.redirectToSavedRequest(req,?resp,?successUrl);????
  • ????????return?false;????
  • ????}????
  • ????private?void?saveRequestAndRedirectToLogin(HttpServletRequest?req,?HttpServletResponse?resp)?throws?IOException?{????
  • ????????WebUtils.saveRequest(req);????
  • ????????WebUtils.issueRedirect(req,?resp,?loginUrl);????
  • ????}????
  • ????
  • ????private?boolean?login(HttpServletRequest?req)?{????
  • ????????String?username?=?req.getParameter("username");????
  • ????????String?password?=?req.getParameter("password");????
  • ????????try?{????
  • ????????????SecurityUtils.getSubject().login(new?UsernamePasswordToken(username,?password));????
  • ????????}?catch?(Exception?e)?{????
  • ????????????req.setAttribute("shiroLoginFailure",?e.getClass());????
  • ????????????return?false;????
  • ????????}????
  • ????????return?true;????
  • ????}????
  • ????private?boolean?isLoginRequest(HttpServletRequest?req)?{????
  • ????????return?pathsMatch(loginUrl,?WebUtils.getPathWithinApplication(req));????
  • ????}????
  • }?????
  • onPreHandle主要流程:
    ??? 1、首先判斷是否已經登錄過了,如果已經登錄過了繼續攔截器鏈即可;
    ??? 2、如果沒有登錄,看看是否是登錄請求,如果是get方法的登錄頁面請求,則繼續攔截器鏈(到請求頁面),否則如果是get方法的其他頁面請求則保存當前請求并重定向到登錄頁面;
    ??? 3、如果是post方法的登錄頁面表單提交請求,則收集用戶名/密碼登錄即可,如果失敗了保存錯誤消息到“shiroLoginFailure”并返回到登錄頁面;
    ??? 4、如果登錄成功了,且之前有保存的請求,則重定向到之前的這個請求,否則到默認的成功頁面。
    shiro.ini配置

    [java] view plain copy print?

  • [filters]????
  • formLogin=com.github.zhangkaitao.shiro.chapter8.web.filter.FormLoginFilter????
  • [urls]????
  • /test.jsp=formLogin????
  • /login.jsp=formLogin?????
  • ??? 啟動服務器輸入http://localhost:8080/chapter8/test.jsp測試時,會自動跳轉到登錄頁面,登錄成功后又會跳回到test.jsp頁面。
    ??? 此處可以通過繼承AuthenticatingFilter實現,其提供了很多登錄相關的基礎代碼。另外可以參考Shiro內嵌的FormAuthenticationFilter的源碼,思路是一樣的。

    6、任意角色授權攔截器
    ??? Shiro提供roles攔截器,其驗證用戶擁有所有角色,沒有提供驗證用戶擁有任意角色的攔截器。

    [java] view plain copy print?

  • public?class?AnyRolesFilter?extends?AccessControlFilter?{????
  • ????private?String?unauthorizedUrl?=?"/unauthorized.jsp";????
  • ????private?String?loginUrl?=?"/login.jsp";????
  • ????protected?boolean?isAccessAllowed(ServletRequest?request,?ServletResponse?response,?Object?mappedValue)?throws?Exception?{????
  • ????????String[]?roles?=?(String[])mappedValue;????
  • ????????if(roles?==?null)?{????
  • ????????????return?true;//如果沒有設置角色參數,默認成功????
  • ????????}????
  • ????????for(String?role?:?roles)?{????
  • ????????????if(getSubject(request,?response).hasRole(role))?{????
  • ????????????????return?true;????
  • ????????????}????
  • ????????}????
  • ????????return?false;//跳到onAccessDenied處理????
  • ????}????
  • ????
  • ????@Override????
  • ????protected?boolean?onAccessDenied(ServletRequest?request,?ServletResponse?response)?throws?Exception?{????
  • ????????Subject?subject?=?getSubject(request,?response);????
  • ????????if?(subject.getPrincipal()?==?null)?{//表示沒有登錄,重定向到登錄頁面????
  • ????????????saveRequest(request);????
  • ????????????WebUtils.issueRedirect(request,?response,?loginUrl);????
  • ????????}?else?{????
  • ????????????if?(StringUtils.hasText(unauthorizedUrl))?{//如果有未授權頁面跳轉過去????
  • ????????????????WebUtils.issueRedirect(request,?response,?unauthorizedUrl);????
  • ????????????}?else?{//否則返回401未授權狀態碼????
  • ????????????????WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);????
  • ????????????}????
  • ????????}????
  • ????????return?false;????
  • ????}????
  • }?????
  • 流程:
    ??? 1、首先判斷用戶有沒有任意角色,如果沒有返回false,將到onAccessDenied進行處理;
    ??? 2、如果用戶沒有角色,接著判斷用戶有沒有登錄,如果沒有登錄先重定向到登錄;
    ??? 3、如果用戶沒有角色且設置了未授權頁面(unauthorizedUrl),那么重定向到未授權頁面;否則直接返回401未授權錯誤碼。
    shiro.ini配置

    [java] view plain copy print?

  • [filters]????
  • anyRoles=com.github.zhangkaitao.shiro.chapter8.web.filter.AnyRolesFilter????
  • [urls]????
  • /test.jsp=formLogin,anyRoles[admin,user]????
  • /login.jsp=formLogin?????
  • ??? 此處可以繼承AuthorizationFilter實現,其提供了授權相關的基礎代碼。另外可以參考Shiro內嵌的RolesAuthorizationFilter的源碼,只是實現hasAllRoles邏輯。

    ?

    ?

    4 默認攔截器

    ??? Shiro內置了很多默認的攔截器,比如身份驗證、授權等相關的。默認攔截器可以參考org.apache.shiro.web.filter.mgt.DefaultFilter中的枚舉攔截器:?

    默認攔截器名

    攔截器類

    說明(括號里的表示默認值)

    身份驗證相關的

    ?

    ?

    authc

    org.apache.shiro.web.filter.authc

    .FormAuthenticationFilter

    基于表單的攔截器;如“/**=authc”,如果沒有登錄會跳到相應的登錄頁面登錄;主要屬性:usernameParam:表單提交的用戶名參數名( username); ?passwordParam:表單提交的密碼參數名(password); rememberMeParam:表單提交的密碼參數名(rememberMe);? loginUrl:登錄頁面地址(/login.jsp);successUrl:登錄成功后的默認重定向地址; failureKeyAttribute:登錄失敗后錯誤信息存儲key(shiroLoginFailure);

    authcBasic

    org.apache.shiro.web.filter.authc

    .BasicHttpAuthenticationFilter

    Basic HTTP身份驗證攔截器,主要屬性: applicationName:彈出登錄框顯示的信息(application);

    logout

    org.apache.shiro.web.filter.authc

    .LogoutFilter

    退出攔截器,主要屬性:redirectUrl:退出成功后重定向的地址(/);示例“/logout=logout”

    user

    org.apache.shiro.web.filter.authc

    .UserFilter

    用戶攔截器,用戶已經身份驗證/記住我登錄的都可;示例“/**=user”

    anon

    org.apache.shiro.web.filter.authc

    .AnonymousFilter

    匿名攔截器,即不需要登錄即可訪問;一般用于靜態資源過濾;示例“/static/**=anon”

    授權相關的

    ?

    ?

    roles

    org.apache.shiro.web.filter.authz

    .RolesAuthorizationFilter

    角色授權攔截器,驗證用戶是否擁有所有角色;主要屬性: loginUrl:登錄頁面地址(/login.jsp);unauthorizedUrl:未授權后重定向的地址;示例“/admin/**=roles[admin]”

    perms

    org.apache.shiro.web.filter.authz

    .PermissionsAuthorizationFilter

    權限授權攔截器,驗證用戶是否擁有所有權限;屬性和roles一樣;示例“/user/**=perms["user:create"]”

    port

    org.apache.shiro.web.filter.authz

    .PortFilter

    端口攔截器,主要屬性:port(80):可以通過的端口;示例“/test= port[80]”,如果用戶訪問該頁面是非80,將自動將請求端口改為80并重定向到該80端口,其他路徑/參數等都一樣

    rest

    org.apache.shiro.web.filter.authz

    .HttpMethodPermissionFilter

    rest風格攔截器,自動根據請求方法構建權限字符串(GET=read, POST=create,PUT=update,DELETE=delete,HEAD=read,TRACE=read,OPTIONS=read, MKCOL=create)構建權限字符串;示例“/users=rest[user]”,會自動拼出“user:read,user:create,user:update,user:delete”權限字符串進行權限匹配(所有都得匹配,isPermittedAll);

    ssl

    org.apache.shiro.web.filter.authz

    .SslFilter

    SSL攔截器,只有請求協議是https才能通過;否則自動跳轉會https端口(443);其他和port攔截器一樣;

    其他

    ?

    ?

    noSessionCreation

    org.apache.shiro.web.filter.session

    .NoSessionCreationFilter

    不創建會話攔截器,調用 subject.getSession(false)不會有什么問題,但是如果 subject.getSession(true)將拋出 DisabledSessionException異常;

    ???? 另外還提供了一個org.apache.shiro.web.filter.authz.HostFilter,即主機攔截器,比如其提供了屬性:authorizedIps:已授權的ip地址,deniedIps:表示拒絕的ip地址;不過目前還沒有完全實現,不可用。
    ??? 這些默認的攔截器會自動注冊,可以直接在ini配置文件中通過“攔截器名.屬性”設置其屬性:

    [java] view plain copy print?

  • perms.unauthorizedUrl=/unauthorized????
  • 另外如果某個攔截器不想使用了可以直接通過如下配置直接禁用:

    [java] view plain copy print?

  • perms.enabled=false????
  • 總結

    以上是生活随笔為你收集整理的shiro学习(19): 拦截器的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。