<!-- shiro過慮器,DelegatingFilterPRox會從spring容器中找shiroFilter -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Shiro 的Web過濾器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- 如果沒有認證將要跳轉的登陸地址,http可訪問的url,如果不在表單認證過慮器FormAuthenticationFilter中指定此地址就為身份認證地址 -->
<property name="loginUrl" value="/login.action" />
<!-- 沒有權限跳轉的地址 -->
<property name="unauthorizedUrl" value="/refuse.jsp" />
<!-- shiro攔截器配置 -->
<property name="filters">
<map>
<entry key="authc" value-ref="formAuthenticationFilter" />
</map>
</property>
<property name="filterChainDefinitions">
<value>
<!-- 必須通過身份認證方可訪問,身份認 證的url必須和過慮器中指定的loginUrl一致 -->
/loginsubmit.action = authc
<!-- 退出攔截,請求logout.action執行退出操作 -->
/logout.action = logout
<!-- 無權訪問頁面 -->
/refuse.jsp = anon
<!-- roles[XX]表示有XX角色才可訪問 -->
/item/list.action = roles[item],authc
/js/** anon
/images/** anon
/styles/** anon
<!-- user表示身份認證通過或通過記住我認證通過的可以訪問 -->
/** = user
<!-- /**放在最下邊,如果一個url有多個過慮器則多個過慮器中間用逗號分隔,如:/** = user,roles[admin] -->
</value>
</property>
</bean>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="userRealm" />
</bean>
<!-- 自定義 realm -->
<bean id="userRealm" class="cn.itcast.ssm.realm.CustomRealm1">
</bean>
<!-- 基于Form表單的身份驗證過濾器,不配置將也會注冊此過慮器,表單中的用戶賬號、密碼及loginurl將采用默認值,建議配置 -->
<bean id="formAuthenticationFilter"
class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
<!-- 表單中賬號的input名稱 -->
<property name="usernameParam" value="usercode" />
<!-- 表單中密碼的input名稱 -->
<property name="passWordParam" value="password" />
<!-- <property name="rememberMeParam" value="rememberMe"/> -->
<!-- loginurl:用戶登陸地址,此地址是可以http訪問的url地址 -->
<property name="loginUrl" value="/loginsubmit.action" />
</bean>
securitymanager:這個屬性是必須的
loginUrl:沒有登錄認證的用戶請求將跳轉到此地址,不是必須的屬性,不輸入地址的話會自動尋找項目web項目的根目錄下的“/login.jsp”頁面
unanthorizedUrl:沒有權限默認跳轉的頁面
在springmvc.xml中配置shiro注解支持,可在controller方法中使用shiro注解配置權限:
<!-- 開啟aop,對類代理 -->
<aop:config proxy-target-class="true"></aop:config>
<!-- 開啟shiro注解支持 -->
<bean
class="
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
修改Controller代碼,在方法上添加授權注解,如下:
// 查詢商品列表
@RequestMapping("/queryItem")
@RequiresPermissions("item:query")
public ModelAndView queryItem() throws Exception {
上邊代碼@RequiresPermissions(“item:query”)表示必須擁有“item:query”權限方可執行。
由于使用shiro的sessionManager,不用開發退出功能,使用shiro的logout攔截器即可。
<!-- 退出攔截,請求logout.action執行退出操作 -->
/logout.action = logout
shiro每個授權都會通過realm獲取權限信息,為了提高訪問速度需要添加緩存,第一次從realm中讀取權限數據,之后不再讀取,這里Shiro和Ehcache整合。
在applicationContext-shiro.xml中配置緩存管理器
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="userRealm" />
<property name="sessionManager" ref="sessionManager" />
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!-- 緩存管理器 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
</bean>
在applicationContext-shiro.xml中配置sessionManager:
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="userRealm" />
<property name="sessionManager" ref="sessionManager" />
</bean>
<!-- 會話管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- session的失效時長,單位毫秒 -->
<property name="globalSessionTimeout" value="600000"/>
<!-- 刪除失效的session -->
<property name="deleteInvalidSessions" value="true"/>
</bean>
需要在驗證賬號和名稱之前校驗驗證碼。
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {
protected boolean onaccessDenied(ServletRequest request,
ServletResponse response, Object mappedValue) throws Exception {
// 校驗驗證碼
// 從session獲取正確的驗證碼
HttpSession session = ((HttpServletRequest)request).getSession();
//頁面輸入的驗證碼
String randomcode = request.getParameter("randomcode");
//從session中取出驗證碼
String validateCode = (String) session.getAttribute("validateCode");
if (!randomcode.equals(validateCode)) {
// randomCodeError表示驗證碼錯誤
request.setAttribute("shiroLoginFailure", "randomCodeError");
//拒絕訪問,不再校驗賬號和密碼
return true;
}
return super.onAccessDenied(request, response, mappedValue);
}
}
修改applicationContext-shiro.xml中對FormAuthenticationFilter的配置。
<bean id="formAuthenticationFilter"
class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter">
改為
<bean id="formAuthenticationFilter"
class="cn.itcast.ssm.shiro.MyFormAuthenticationFilter">
用戶登錄選擇“自動登錄”本次登錄成功會向cookie寫身份信息,下次登錄從cookie中取出身份信息實現自動登錄。
向cookie記錄身份信息需要用戶身份信息對象實現序列化接口。
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="userRealm" />
<property name="sessionManager" ref="sessionManager" />
<property name="cacheManager" ref="cacheManager"/>
<!-- 記住我 -->
<property name="rememberMeManager" ref="rememberMeManager"/>
</bean>
<!-- rememberMeManager管理器 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cookie" ref="rememberMeCookie" />
</bean>
<!-- 記住我cookie -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe" />
<!-- 記住我cookie生效時間30天 -->
<property name="maxAge" value="2592000" />
</bean>
修改formAuthenticationFitler添加頁面中“記住我checkbox”的input名稱:
<bean id="formAuthenticationFilter"
class="cn.itcast.ssm.shiro.MyFormAuthenticationFilter">
<!-- 表單中賬號的input名稱 -->
<property name="usernameParam" value="usercode" />
<!-- 表單中密碼的input名稱 -->
<property name="passwordParam" value="password" />
<property name="rememberMeParam" value="rememberMe"/>
<!-- loginurl:用戶登陸地址,此地址是可以http訪問的url地址 -->
<property name="loginUrl" value="/loginsubmit.action" />
</bean>
新聞熱點
疑難解答