Shiro 攔截器機制

2021-03-12 15:40 更新

攔截器機制

攔截器介紹

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

1、NameableFilter
NameableFilter 給 Filter 起個名字,如果沒有設(shè)置默認(rèn)就是 FilterName;還記得之前的如 authc 嗎?當(dāng)我們組裝攔截器鏈時會根據(jù)這個名字找到相應(yīng)的攔截器實例;

2、OncePerRequestFilter
OncePerRequestFilter 用于防止多次執(zhí)行 Filter 的;也就是說一次請求只會走一次攔截器鏈;另外提供 enabled 屬性,表示是否開啟該攔截器實例,默認(rèn) enabled=true 表示開啟,如果不想讓某個攔截器工作,可以設(shè)置為 false 即可。

3、ShiroFilter
ShiroFilter 是整個 Shiro 的入口點,用于攔截需要安全控制的請求進行處理,這個之前已經(jīng)用過了。

4、AdviceFilter
AdviceFilter 提供了 AOP 風(fēng)格的支持,類似于 SpringMVC 中的 Interceptor:

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 中的前置增強;在攔截器鏈執(zhí)行之前執(zhí)行;如果返回 true 則繼續(xù)攔截器鏈;否則中斷后續(xù)的攔截器鏈的執(zhí)行直接返回;進行預(yù)處理(如基于表單的身份驗證、授權(quán))
  • postHandle:類似于 AOP 中的后置返回增強;在攔截器鏈執(zhí)行完成后執(zhí)行;進行后處理(如記錄執(zhí)行時間之類的);
  • afterCompletion:類似于 AOP 中的后置最終增強;即不管有沒有異常都會執(zhí)行;可以進行清理資源(如解除 Subject 與線程的綁定之類的);

5、PathMatchingFilter

PathMatchingFilter 提供了基于 Ant 風(fēng)格的請求路徑匹配功能及攔截器參數(shù)解析的功能,如“roles[admin,user]”自動根據(jù)“,”分割解析到一個路徑參數(shù)配置并綁定到相應(yīng)的路徑:

boolean pathsMatch(String path, ServletRequest request)
boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception

pathsMatch:該方法用于 path 與請求路徑進行匹配的方法;如果匹配返回 true;
onPreHandle:在 preHandle 中,當(dāng) pathsMatch 匹配一個路徑后,會調(diào)用 opPreHandler 方法并將路徑綁定參數(shù)配置傳給 mappedValue;然后可以在這個方法中進行一些驗證(如角色授權(quán)),如果驗證失敗可以返回 false 中斷流程;默認(rèn)返回 true;也就是說子類可以只實現(xiàn) onPreHandle 即可,無須實現(xiàn) preHandle。如果沒有 path 與請求路徑匹配,默認(rèn)是通過的(即 preHandle 返回 true)。

6、AccessControlFilter

AccessControlFilter 提供了訪問控制的基礎(chǔ)功能;比如是否允許訪問/當(dāng)訪問拒絕時如何處理等:

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]配置中攔截器參數(shù)部分,如果允許訪問返回 true,否則 false;

onAccessDenied:表示當(dāng)訪問拒絕時是否已經(jīng)處理了;如果返回 true 表示需要繼續(xù)處理;如果返回 false 表示該攔截器實例已經(jīng)處理了,將直接返回即可。

onPreHandle 會自動調(diào)用這兩個方法決定是否繼續(xù)處理:

boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
    return isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response, mappedValue);
}

另外 AccessControlFilter 還提供了如下方法用于處理如登錄成功后/重定向到上一個請求:

void setLoginUrl(String loginUrl) //身份驗證時使用,默認(rèn)/login.jsp
String getLoginUrl()
Subject getSubject(ServletRequest request, ServletResponse response) //獲取Subject 實例
boolean isLoginRequest(ServletRequest request, ServletResponse response)//當(dāng)前請求是否是登錄請求
void saveRequestAndRedirectToLogin(ServletRequest request, ServletResponse response) throws IOException //將當(dāng)前請求保存起來并重定向到登錄頁面
void saveRequest(ServletRequest request) //將請求保存起來,如登錄成功后再重定向回該請求
void redirectToLogin(ServletRequest request, ServletResponse response) //重定向到登錄頁面 

比如基于表單的身份驗證就需要使用這些功能。

到此基本的攔截器就完事了,如果我們想進行訪問訪問的控制就可以繼承 AccessControlFilter;如果我們要添加一些通用數(shù)據(jù)我們可以直接繼承 PathMatchingFilter。

攔截器鏈

Shiro 對 Servlet 容器的 FilterChain 進行了代理,即 ShiroFilter 在繼續(xù) Servlet 容器的 Filter 鏈的執(zhí)行之前,通過 ProxiedFilterChain 對 Servlet 容器的 FilterChain 進行了代理;即先走 Shiro 自己的 Filter 體系,然后才會委托給 Servlet 容器的 FilterChain 進行 Servlet 容器級別的 Filter 鏈執(zhí)行;Shiro 的 ProxiedFilterChain 執(zhí)行流程:1、先執(zhí)行 Shiro 自己的 Filter 鏈;2、再執(zhí)行 Servlet 容器的 Filter 鏈(即原始的 Filter)。

而 ProxiedFilterChain 是通過 FilterChainResolver 根據(jù)配置文件中[urls]部分是否與請求的 URL 是否匹配解析得到的。

FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain);

即傳入原始的 chain 得到一個代理的 chain。

Shiro 內(nèi)部提供了一個路徑匹配的 FilterChainResolver 實現(xiàn):PathMatchingFilterChainResolver,其根據(jù)[urls]中配置的 url 模式(默認(rèn) Ant 風(fēng)格)=攔截器鏈和請求的 url 是否匹配來解析得到配置的攔截器鏈的;而 PathMatchingFilterChainResolver 內(nèi)部通過 FilterChainManager 維護著攔截器鏈,比如 DefaultFilterChainManager 實現(xiàn)維護著 url 模式與攔截器鏈的關(guān)系。因此我們可以通過 FilterChainManager 進行動態(tài)動態(tài)增加 url 模式與攔截器鏈的關(guān)系。

DefaultFilterChainManager 會默認(rèn)添加 org.apache.shiro.web.filter.mgt.DefaultFilter 中聲明的攔截器:

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);
}

下一節(jié)會介紹這些攔截器的作用。

如果要注冊自定義攔截器,IniSecurityManagerFactory/WebIniSecurityManagerFactory 在啟動時會自動掃描 ini 配置文件中的 [filters]/[main] 部分并注冊這些攔截器到 DefaultFilterChainManager;且創(chuàng)建相應(yīng)的 url 模式與其攔截器關(guān)系鏈。如果使用 Spring 后續(xù)章節(jié)會介紹如果注冊自定義攔截器。

如果想自定義 FilterChainResolver,可以通過實現(xiàn) WebEnvironment 接口完成:

public class MyIniWebEnvironment extends IniWebEnvironment {
    @Override
    protected FilterChainResolver createFilterChainResolver() {
        //在此處擴展自己的FilterChainResolver
        return super.createFilterChainResolver();
    }
}

FilterChain 之間的關(guān)系。如果想動態(tài)實現(xiàn) url -攔截器的注冊,就可以通過實現(xiàn)此處的 FilterChainResolver 來完成,比如:

//1、創(chuàng)建 FilterChainResolver
PathMatchingFilterChainResolver filterChainResolver =
        new PathMatchingFilterChainResolver();
//2、創(chuàng)建 FilterChainManager
DefaultFilterChainManager filterChainManager = new DefaultFilterChainManager();
//3、注冊 Filter
for(DefaultFilter filter : DefaultFilter.values()) {
    filterChainManager.addFilter(
        filter.name(), (Filter) ClassUtils.newInstance(filter.getFilterClass()));
}
//4、注冊 URL-Filter 的映射關(guān)系
filterChainManager.addToChain("/login.jsp", "authc");
filterChainManager.addToChain("/unauthorized.jsp", "anon");
filterChainManager.addToChain("/**", "authc");
filterChainManager.addToChain("/**", "roles", "admin");
//5、設(shè)置 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;

此處自己去實現(xiàn)注冊 filter,及url 模式與 filter 之間的映射關(guān)系??梢酝ㄟ^定制 FilterChainResolver 或 FilterChainManager 來完成諸如動態(tài) URL 匹配的實現(xiàn)。

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

<context-param>
<param-name>shiroEnvironmentClass</param-name> <param-value>com.github.zhangkaitao.shiro.chapter8.web.env.MyIniWebEnvironment</param-value>
</context-param>

自定義攔截器

通過自定義自己的攔截器可以擴展一些功能,諸如動態(tài) url -角色/權(quán)限訪問控制的實現(xiàn)、根據(jù) Subject 身份信息獲取用戶信息綁定到 Request(即設(shè)置通用數(shù)據(jù))、驗證碼驗證、在線用戶信息的保存等等,因為其本質(zhì)就是一個 Filter;所以 Filter 能做的它就能做。

對于 Filter 的介紹請參考《Servlet規(guī)范》中的 Filter 部分:
http://www.iteye.com/blogs/subjects/Servlet-3-1。

1、擴展 OncePerRequestFilter

OncePerRequestFilter 保證一次請求只調(diào)用一次 doFilterInternal,即如內(nèi)部的 forward 不會再多執(zhí)行一次 doFilterInternal:

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 配置文件中:

[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 的映射關(guān)系即可。

2、擴展 AdviceFilter

AdviceFilter 提供了 AOP 的功能,其實現(xiàn)和 SpringMVC 中的 Interceptor 思想一樣:具體可參考我的 SpringMVC 教程中的處理器攔截器部分:
http://www.iteye.com/blogs/subjects/kaitao-springmvc

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

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

[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:

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 進行匹配,如果匹配會調(diào)用 onPreHandle;如果沒有配置 url 模式 / 沒有 url 模式匹配,默認(rèn)直接返回 true;
  • onPreHandle:如果 url 模式與請求 url 匹配,那么會執(zhí)行 onPreHandle,并把該攔截器配置的參數(shù)傳入。默認(rèn)什么不處理直接返回 true。

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

[filters]
myFilter3=com.github.zhangkaitao.shiro.chapter8.web.filter.MyPathMatchingFilter
[urls]
/**= myFilter3[config]

/** 就是注冊給 PathMatchingFilter 的 url 模式,config 就是攔截器的配置參數(shù),多個之間逗號分隔,onPreHandle 使用 mappedValue 接收參數(shù)值。

4、擴展 AccessControlFilter

AccessControlFilter 繼承了 PathMatchingFilter,并擴展了了兩個方法:

public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
    return isAccessAllowed(request, response, mappedValue)
     || onAccessDenied(request, response, mappedValue);
}

isAccessAllowed:即是否允許訪問,返回 true 表示允許;
onAccessDenied:表示訪問拒絕時是否自己處理,如果返回 true 表示自己不處理且繼續(xù)攔截器鏈執(zhí)行,返回 false 表示自己已經(jīng)處理了(比如重定向到另一個頁面)。

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("訪問拒絕也不自己處理,繼續(xù)攔截器鏈的執(zhí)行");
        return true;
    }
}

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

5、基于表單登錄攔截器

之前我們已經(jīng)使用過 Shiro 內(nèi)置的基于表單登錄的攔截器了,此處自己做一個類似的基于表單登錄的攔截器。

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;//已經(jīng)登錄過
        }
        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;//繼續(xù)過濾器鏈
        } else {//保存當(dāng)前地址并重定向到登錄界面
            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. 首先判斷是否已經(jīng)登錄過了,如果已經(jīng)登錄過了繼續(xù)攔截器鏈即可;
  2. 如果沒有登錄,看看是否是登錄請求,如果是 get 方法的登錄頁面請求,則繼續(xù)攔截器鏈(到請求頁面),否則如果是 get 方法的其他頁面請求則保存當(dāng)前請求并重定向到登錄頁面;
  3. 如果是 post 方法的登錄頁面表單提交請求,則收集用戶名 / 密碼登錄即可,如果失敗了保存錯誤消息到 “shiroLoginFailure” 并返回到登錄頁面;
  4. 如果登錄成功了,且之前有保存的請求,則重定向到之前的這個請求,否則到默認(rèn)的成功頁面。

shiro.ini 配置

[filters]
formLogin=com.github.zhangkaitao.shiro.chapter8.web.filter.FormLoginFilter
[urls]
/test.jsp=formLogin
/login.jsp=formLogin

啟動服務(wù)器輸入 http://localhost:8080/chapter8/test.jsp 測試時,會自動跳轉(zhuǎn)到登錄頁面,登錄成功后又會跳回到 test.jsp 頁面。

此處可以通過繼承 AuthenticatingFilter 實現(xiàn),其提供了很多登錄相關(guān)的基礎(chǔ)代碼。另外可以參考 Shiro 內(nèi)嵌的 FormAuthenticationFilter 的源碼,思路是一樣的。

6、任意角色授權(quán)攔截器

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

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;//如果沒有設(shè)置角色參數(shù),默認(rèn)成功
        }
        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)) {//如果有未授權(quán)頁面跳轉(zhuǎn)過去
                WebUtils.issueRedirect(request, response, unauthorizedUrl);
            } else {//否則返回401未授權(quán)狀態(tài)碼
                WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
            }
        }
        return false;
    }
} 

流程:

  1. 首先判斷用戶有沒有任意角色,如果沒有返回 false,將到 onAccessDenied 進行處理;
  2. 如果用戶沒有角色,接著判斷用戶有沒有登錄,如果沒有登錄先重定向到登錄;
  3. 如果用戶沒有角色且設(shè)置了未授權(quán)頁面(unauthorizedUrl),那么重定向到未授權(quán)頁面;否則直接返回 401 未授權(quán)錯誤碼。

shiro.ini 配置

[filters]
anyRoles=com.github.zhangkaitao.shiro.chapter8.web.filter.AnyRolesFilter
[urls]
/test.jsp=formLogin,anyRoles[admin,user]
/login.jsp=formLogin

此處可以繼承 AuthorizationFilter 實現(xiàn),其提供了授權(quán)相關(guān)的基礎(chǔ)代碼。另外可以參考 Shiro 內(nèi)嵌的 RolesAuthorizationFilter 的源碼,只是實現(xiàn) hasAllRoles 邏輯。

默認(rèn)攔截器

Shiro 內(nèi)置了很多默認(rèn)的攔截器,比如身份驗證、授權(quán)等相關(guān)的。默認(rèn)攔截器可以參考 org.apache.shiro.web.filter.mgt.DefaultFilter 中的枚舉攔截器:

默認(rèn)攔截器名

攔截器類

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

身份驗證相關(guān)的

 

 

authc

org.apache.shiro.web.filter.authc

.FormAuthenticationFilter

基于表單的攔截器;如 “`/**=authc`”,如果沒有登錄會跳到相應(yīng)的登錄頁面登錄;主要屬性:usernameParam:表單提交的用戶名參數(shù)名( username);  passwordParam:表單提交的密碼參數(shù)名(password); rememberMeParam:表單提交的密碼參數(shù)名(rememberMe);  loginUrl:登錄頁面地址(/login.jsp);successUrl:登錄成功后的默認(rèn)重定向地址; 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

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

anon

org.apache.shiro.web.filter.authc

.AnonymousFilter

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

授權(quán)相關(guān)的

 

 

roles

org.apache.shiro.web.filter.authz

.RolesAuthorizationFilter

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

perms

org.apache.shiro.web.filter.authz

.PermissionsAuthorizationFilter

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

port

org.apache.shiro.web.filter.authz

.PortFilter

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

rest

org.apache.shiro.web.filter.authz

.HttpMethodPermissionFilter

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

ssl

org.apache.shiro.web.filter.authz

.SslFilter

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

其他

 

 

noSessionCreation

org.apache.shiro.web.filter.session

.NoSessionCreationFilter

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

另外還提供了一個 org.apache.shiro.web.filter.authz.HostFilter,即主機攔截器,比如其提供了屬性:authorizedIps:已授權(quán)的 ip 地址,deniedIps:表示拒絕的 ip 地址;不過目前還沒有完全實現(xiàn),不可用。

這些默認(rèn)的攔截器會自動注冊,可以直接在 ini 配置文件中通過 “攔截器名. 屬性” 設(shè)置其屬性:

perms.unauthorizedUrl=/unauthorized

另外如果某個攔截器不想使用了可以直接通過如下配置直接禁用:

perms.enabled=false

示例源代碼:[https://github.com/zhangkaitao/shiro-example]()

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號