Shiro 使用了與 Servlet 一樣的 Filter 接口進(jìn)行擴(kuò)展;所以如果對(duì) Filter 不熟悉可以參考《Servlet 3.1 規(guī)范》http://www.iteye.com/blogs/subjects/Servlet-3-1了解 Filter 的工作原理。首先下圖是 Shiro 攔截器的基礎(chǔ)類(lèi)圖:
1、NameableFilter
NameableFilter 給 Filter 起個(gè)名字,如果沒(méi)有設(shè)置默認(rèn)就是 FilterName;還記得之前的如 authc 嗎?當(dāng)我們組裝攔截器鏈時(shí)會(huì)根據(jù)這個(gè)名字找到相應(yīng)的攔截器實(shí)例;
2、OncePerRequestFilter
OncePerRequestFilter 用于防止多次執(zhí)行 Filter 的;也就是說(shuō)一次請(qǐng)求只會(huì)走一次攔截器鏈;另外提供 enabled 屬性,表示是否開(kāi)啟該攔截器實(shí)例,默認(rèn) enabled=true 表示開(kāi)啟,如果不想讓某個(gè)攔截器工作,可以設(shè)置為 false 即可。
3、ShiroFilter
ShiroFilter 是整個(gè) Shiro 的入口點(diǎn),用于攔截需要安全控制的請(qǐng)求進(jìn)行處理,這個(gè)之前已經(jīng)用過(guò)了。
4、AdviceFilter
AdviceFilter 提供了 AOP 風(fēng)格的支持,類(lèi)似于 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;
5、PathMatchingFilter
PathMatchingFilter 提供了基于 Ant 風(fēng)格的請(qǐng)求路徑匹配功能及攔截器參數(shù)解析的功能,如“roles[admin,user]”自動(dòng)根據(jù)“,”分割解析到一個(gè)路徑參數(shù)配置并綁定到相應(yīng)的路徑:
boolean pathsMatch(String path, ServletRequest request)
boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception
pathsMatch:該方法用于 path 與請(qǐng)求路徑進(jìn)行匹配的方法;如果匹配返回 true;
onPreHandle:在 preHandle 中,當(dāng) pathsMatch 匹配一個(gè)路徑后,會(huì)調(diào)用 opPreHandler 方法并將路徑綁定參數(shù)配置傳給 mappedValue;然后可以在這個(gè)方法中進(jìn)行一些驗(yàn)證(如角色授權(quán)),如果驗(yàn)證失敗可以返回 false 中斷流程;默認(rèn)返回 true;也就是說(shuō)子類(lèi)可以只實(shí)現(xiàn) onPreHandle 即可,無(wú)須實(shí)現(xiàn) preHandle。如果沒(méi)有 path 與請(qǐng)求路徑匹配,默認(rèn)是通過(guò)的(即 preHandle 返回 true)。
6、AccessControlFilter
AccessControlFilter 提供了訪問(wèn)控制的基礎(chǔ)功能;比如是否允許訪問(wèn)/當(dāng)訪問(wèn)拒絕時(shí)如何處理等:
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:表示是否允許訪問(wèn);mappedValue 就是[urls]配置中攔截器參數(shù)部分,如果允許訪問(wèn)返回 true,否則 false;
onAccessDenied:表示當(dāng)訪問(wèn)拒絕時(shí)是否已經(jīng)處理了;如果返回 true 表示需要繼續(xù)處理;如果返回 false 表示該攔截器實(shí)例已經(jīng)處理了,將直接返回即可。
onPreHandle 會(huì)自動(dòng)調(diào)用這兩個(gè)方法決定是否繼續(xù)處理:
boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
return isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response, mappedValue);
}
另外 AccessControlFilter 還提供了如下方法用于處理如登錄成功后/重定向到上一個(gè)請(qǐng)求:
void setLoginUrl(String loginUrl) //身份驗(yàn)證時(shí)使用,默認(rèn)/login.jsp
String getLoginUrl()
Subject getSubject(ServletRequest request, ServletResponse response) //獲取Subject 實(shí)例
boolean isLoginRequest(ServletRequest request, ServletResponse response)//當(dāng)前請(qǐng)求是否是登錄請(qǐng)求
void saveRequestAndRedirectToLogin(ServletRequest request, ServletResponse response) throws IOException //將當(dāng)前請(qǐng)求保存起來(lái)并重定向到登錄頁(yè)面
void saveRequest(ServletRequest request) //將請(qǐng)求保存起來(lái),如登錄成功后再重定向回該請(qǐng)求
void redirectToLogin(ServletRequest request, ServletResponse response) //重定向到登錄頁(yè)面
比如基于表單的身份驗(yàn)證就需要使用這些功能。
到此基本的攔截器就完事了,如果我們想進(jìn)行訪問(wèn)訪問(wèn)的控制就可以繼承 AccessControlFilter;如果我們要添加一些通用數(shù)據(jù)我們可以直接繼承 PathMatchingFilter。
Shiro 對(duì) Servlet 容器的 FilterChain 進(jìn)行了代理,即 ShiroFilter 在繼續(xù) Servlet 容器的 Filter 鏈的執(zhí)行之前,通過(guò) ProxiedFilterChain 對(duì) Servlet 容器的 FilterChain 進(jìn)行了代理;即先走 Shiro 自己的 Filter 體系,然后才會(huì)委托給 Servlet 容器的 FilterChain 進(jìn)行 Servlet 容器級(jí)別的 Filter 鏈執(zhí)行;Shiro 的 ProxiedFilterChain 執(zhí)行流程:1、先執(zhí)行 Shiro 自己的 Filter 鏈;2、再執(zhí)行 Servlet 容器的 Filter 鏈(即原始的 Filter)。
而 ProxiedFilterChain 是通過(guò) FilterChainResolver 根據(jù)配置文件中[urls]部分是否與請(qǐng)求的 URL 是否匹配解析得到的。
FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain);
即傳入原始的 chain 得到一個(gè)代理的 chain。
Shiro 內(nèi)部提供了一個(gè)路徑匹配的 FilterChainResolver 實(shí)現(xiàn):PathMatchingFilterChainResolver,其根據(jù)[urls]中配置的 url 模式(默認(rèn) Ant 風(fēng)格)=攔截器鏈和請(qǐng)求的 url 是否匹配來(lái)解析得到配置的攔截器鏈的;而 PathMatchingFilterChainResolver 內(nèi)部通過(guò) FilterChainManager 維護(hù)著攔截器鏈,比如 DefaultFilterChainManager 實(shí)現(xiàn)維護(hù)著 url 模式與攔截器鏈的關(guān)系。因此我們可以通過(guò) FilterChainManager 進(jìn)行動(dòng)態(tài)動(dòng)態(tài)增加 url 模式與攔截器鏈的關(guān)系。
DefaultFilterChainManager 會(huì)默認(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é)會(huì)介紹這些攔截器的作用。
如果要注冊(cè)自定義攔截器,IniSecurityManagerFactory/WebIniSecurityManagerFactory 在啟動(dòng)時(shí)會(huì)自動(dòng)掃描 ini 配置文件中的 [filters]/[main] 部分并注冊(cè)這些攔截器到 DefaultFilterChainManager;且創(chuàng)建相應(yīng)的 url 模式與其攔截器關(guān)系鏈。如果使用 Spring 后續(xù)章節(jié)會(huì)介紹如果注冊(cè)自定義攔截器。
如果想自定義 FilterChainResolver,可以通過(guò)實(shí)現(xiàn) WebEnvironment 接口完成:
public class MyIniWebEnvironment extends IniWebEnvironment {
@Override
protected FilterChainResolver createFilterChainResolver() {
//在此處擴(kuò)展自己的FilterChainResolver
return super.createFilterChainResolver();
}
}
FilterChain 之間的關(guān)系。如果想動(dòng)態(tài)實(shí)現(xiàn) url -攔截器的注冊(cè),就可以通過(guò)實(shí)現(xiàn)此處的 FilterChainResolver 來(lái)完成,比如:
//1、創(chuàng)建 FilterChainResolver
PathMatchingFilterChainResolver filterChainResolver =
new PathMatchingFilterChainResolver();
//2、創(chuàng)建 FilterChainManager
DefaultFilterChainManager filterChainManager = new DefaultFilterChainManager();
//3、注冊(cè) Filter
for(DefaultFilter filter : DefaultFilter.values()) {
filterChainManager.addFilter(
filter.name(), (Filter) ClassUtils.newInstance(filter.getFilterClass()));
}
//4、注冊(cè) 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;
此處自己去實(shí)現(xiàn)注冊(cè) filter,及url 模式與 filter 之間的映射關(guān)系??梢酝ㄟ^(guò)定制 FilterChainResolver 或 FilterChainManager 來(lái)完成諸如動(dòng)態(tài) URL 匹配的實(shí)現(xiàn)。
然后再 web.xml 中進(jìn)行如下配置 Environment:
<context-param>
<param-name>shiroEnvironmentClass</param-name> <param-value>com.github.zhangkaitao.shiro.chapter8.web.env.MyIniWebEnvironment</param-value>
</context-param>
通過(guò)自定義自己的攔截器可以擴(kuò)展一些功能,諸如動(dòng)態(tài) url -角色/權(quán)限訪問(wèn)控制的實(shí)現(xiàn)、根據(jù) Subject 身份信息獲取用戶信息綁定到 Request(即設(shè)置通用數(shù)據(jù))、驗(yàn)證碼驗(yàn)證、在線用戶信息的保存等等,因?yàn)槠浔举|(zhì)就是一個(gè) Filter;所以 Filter 能做的它就能做。
對(duì)于 Filter 的介紹請(qǐng)參考《Servlet規(guī)范》中的 Filter 部分:
http://www.iteye.com/blogs/subjects/Servlet-3-1。
1、擴(kuò)展 OncePerRequestFilter
OncePerRequestFilter 保證一次請(qǐng)求只調(diào)用一次 doFilterInternal,即如內(nèi)部的 forward 不會(huì)再多執(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] 部分注冊(cè),然后在 [urls] 部分配置 url 與 filter 的映射關(guān)系即可。
2、擴(kuò)展 AdviceFilter
AdviceFilter 提供了 AOP 的功能,其實(shí)現(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("====完成處理/后置最終處理");
}
}
然后在 shiro.ini 中進(jìn)行如下配置:
[filters]
myFilter1=com.github.zhangkaitao.shiro.chapter8.web.filter.MyOncePerRequestFilter
myFilter2=com.github.zhangkaitao.shiro.chapter8.web.filter.MyAdviceFilter
[urls]
/**=myFilter1,myFilter2
該過(guò)濾器的具體使用可參考我的 SpringMVC 教程中的處理器攔截器部分。
3、PathMatchingFilter
PathMatchingFilter 繼承了 AdviceFilter,提供了 url 模式過(guò)濾的功能,如果需要對(duì)指定的請(qǐng)求進(jìn)行處理,可以擴(kuò)展 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;
}
}
然后在 shiro.ini 中進(jìn)行如下配置:
[filters]
myFilter3=com.github.zhangkaitao.shiro.chapter8.web.filter.MyPathMatchingFilter
[urls]
/**= myFilter3[config]
/**
就是注冊(cè)給 PathMatchingFilter 的 url 模式,config 就是攔截器的配置參數(shù),多個(gè)之間逗號(hào)分隔,onPreHandle 使用 mappedValue 接收參數(shù)值。
4、擴(kuò)展 AccessControlFilter
AccessControlFilter 繼承了 PathMatchingFilter,并擴(kuò)展了了兩個(gè)方法:
public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
return isAccessAllowed(request, response, mappedValue)
|| onAccessDenied(request, response, mappedValue);
}
isAccessAllowed:即是否允許訪問(wèn),返回 true 表示允許;
onAccessDenied:表示訪問(wèn)拒絕時(shí)是否自己處理,如果返回 true 表示自己不處理且繼續(xù)攔截器鏈執(zhí)行,返回 false 表示自己已經(jīng)處理了(比如重定向到另一個(gè)頁(yè)面)。
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("訪問(wèn)拒絕也不自己處理,繼續(xù)攔截器鏈的執(zhí)行");
return true;
}
}
然后在 shiro.ini 中進(jìn)行如下配置:
5、基于表單登錄攔截器
之前我們已經(jīng)使用過(guò) Shiro 內(nèi)置的基于表單登錄的攔截器了,此處自己做一個(gè)類(lè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)登錄過(guò)
}
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ù)過(guò)濾器鏈
} 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 主要流程:
shiro.ini 配置
[filters]
formLogin=com.github.zhangkaitao.shiro.chapter8.web.filter.FormLoginFilter
[urls]
/test.jsp=formLogin
/login.jsp=formLogin
啟動(dòng)服務(wù)器輸入 http://localhost:8080/chapter8/test.jsp
測(cè)試時(shí),會(huì)自動(dòng)跳轉(zhuǎn)到登錄頁(yè)面,登錄成功后又會(huì)跳回到 test.jsp 頁(yè)面。
此處可以通過(guò)繼承 AuthenticatingFilter 實(shí)現(xiàn),其提供了很多登錄相關(guān)的基礎(chǔ)代碼。另外可以參考 Shiro 內(nèi)嵌的 FormAuthenticationFilter 的源碼,思路是一樣的。
6、任意角色授權(quán)攔截器
Shiro 提供 roles 攔截器,其驗(yàn)證用戶擁有所有角色,沒(méi)有提供驗(yàn)證用戶擁有任意角色的攔截器。
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;//如果沒(méi)有設(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) {//表示沒(méi)有登錄,重定向到登錄頁(yè)面
saveRequest(request);
WebUtils.issueRedirect(request, response, loginUrl);
} else {
if (StringUtils.hasText(unauthorizedUrl)) {//如果有未授權(quán)頁(yè)面跳轉(zhuǎn)過(guò)去
WebUtils.issueRedirect(request, response, unauthorizedUrl);
} else {//否則返回401未授權(quán)狀態(tài)碼
WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
}
return false;
}
}
流程:
shiro.ini 配置
[filters]
anyRoles=com.github.zhangkaitao.shiro.chapter8.web.filter.AnyRolesFilter
[urls]
/test.jsp=formLogin,anyRoles[admin,user]
/login.jsp=formLogin
此處可以繼承 AuthorizationFilter 實(shí)現(xiàn),其提供了授權(quán)相關(guān)的基礎(chǔ)代碼。另外可以參考 Shiro 內(nèi)嵌的 RolesAuthorizationFilter 的源碼,只是實(shí)現(xiàn) hasAllRoles 邏輯。
Shiro 內(nèi)置了很多默認(rèn)的攔截器,比如身份驗(yàn)證、授權(quán)等相關(guān)的。默認(rèn)攔截器可以參考 org.apache.shiro.web.filter.mgt.DefaultFilter 中的枚舉攔截器:
默認(rèn)攔截器名 |
攔截器類(lèi) |
說(shuō)明(括號(hào)里的表示默認(rèn)值) |
身份驗(yàn)證相關(guān)的 |
|
|
authc |
org.apache.shiro.web.filter.authc .FormAuthenticationFilter |
基于表單的攔截器;如 “`/**=authc`”,如果沒(méi)有登錄會(huì)跳到相應(yīng)的登錄頁(yè)面登錄;主要屬性:usernameParam:表單提交的用戶名參數(shù)名( username); passwordParam:表單提交的密碼參數(shù)名(password); rememberMeParam:表單提交的密碼參數(shù)名(rememberMe); loginUrl:登錄頁(yè)面地址(/login.jsp);successUrl:登錄成功后的默認(rèn)重定向地址; failureKeyAttribute:登錄失敗后錯(cuò)誤信息存儲(chǔ) key(shiroLoginFailure); |
authcBasic |
org.apache.shiro.web.filter.authc .BasicHttpAuthenticationFilter |
Basic HTTP 身份驗(yàn)證攔截器,主要屬性: applicationName:彈出登錄框顯示的信息(application); |
logout |
org.apache.shiro.web.filter.authc .LogoutFilter |
退出攔截器,主要屬性:redirectUrl:退出成功后重定向的地址(/); 示例 “/logout=logout” |
user |
org.apache.shiro.web.filter.authc .UserFilter |
用戶攔截器,用戶已經(jīng)身份驗(yàn)證 / 記住我登錄的都可;示例 “/**=user” |
anon |
org.apache.shiro.web.filter.authc .AnonymousFilter |
匿名攔截器,即不需要登錄即可訪問(wèn);一般用于靜態(tài)資源過(guò)濾;示例 “/static/**=anon” |
授權(quán)相關(guān)的 |
|
|
roles |
org.apache.shiro.web.filter.authz .RolesAuthorizationFilter |
角色授權(quán)攔截器,驗(yàn)證用戶是否擁有所有角色;主要屬性: loginUrl:登錄頁(yè)面地址(/login.jsp);unauthorizedUrl:未授權(quán)后重定向的地址;示例 “/admin/**=roles[admin]” |
perms |
org.apache.shiro.web.filter.authz .PermissionsAuthorizationFilter |
權(quán)限授權(quán)攔截器,驗(yàn)證用戶是否擁有所有權(quán)限;屬性和 roles 一樣;示例 “/user/**=perms["user:create"]” |
port |
org.apache.shiro.web.filter.authz .PortFilter |
端口攔截器,主要屬性:port(80):可以通過(guò)的端口;示例 “/test= port[80]”,如果用戶訪問(wèn)該頁(yè)面是非 80,將自動(dòng)將請(qǐng)求端口改為 80 并重定向到該 80 端口,其他路徑 / 參數(shù)等都一樣 |
rest |
org.apache.shiro.web.filter.authz .HttpMethodPermissionFilter |
rest 風(fēng)格攔截器,自動(dòng)根據(jù)請(qǐng)求方法構(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]”,會(huì)自動(dòng)拼出“user:read,user:create,user:update,user:delete” 權(quán)限字符串進(jìn)行權(quán)限匹配(所有都得匹配,isPermittedAll); |
ssl |
org.apache.shiro.web.filter.authz .SslFilter |
SSL 攔截器,只有請(qǐng)求協(xié)議是 https 才能通過(guò);否則自動(dòng)跳轉(zhuǎn)會(huì) https 端口(443);其他和 port 攔截器一樣; |
其他 |
|
|
noSessionCreation |
org.apache.shiro.web.filter.session .NoSessionCreationFilter |
不創(chuàng)建會(huì)話攔截器,調(diào)用 subject.getSession(false) 不會(huì)有什么問(wèn)題,但是如果 subject.getSession(true) 將拋出 DisabledSessionException 異常; |
另外還提供了一個(gè) org.apache.shiro.web.filter.authz.HostFilter,即主機(jī)攔截器,比如其提供了屬性:authorizedIps:已授權(quán)的 ip 地址,deniedIps:表示拒絕的 ip 地址;不過(guò)目前還沒(méi)有完全實(shí)現(xiàn),不可用。
這些默認(rèn)的攔截器會(huì)自動(dòng)注冊(cè),可以直接在 ini 配置文件中通過(guò) “攔截器名. 屬性” 設(shè)置其屬性:
perms.unauthorizedUrl=/unauthorized
另外如果某個(gè)攔截器不想使用了可以直接通過(guò)如下配置直接禁用:
perms.enabled=false
更多建議: