shiro安全控制目錄
1. 導(dǎo)入依賴
<properties>
<shiro.version>1.2.3</shiro.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
</dependencies>
2. web.xml配置
在web.xml中,將攔截器交由Spring管理。shiro(3)-Filter交由Spring管理-DelegatingFilterProxy。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>helloworld</display-name>
<!-- 讀取spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring/applicationContext.xml,
classpath:/spring/application-shiro.xml,
classpath:/spring/spring-mybatis.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--攔截器由spring容器管理-->
<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>
<!-- springMVC核心配置 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 攔截設(shè)置 -->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
注:設(shè)置targetFilterLifecycle=true的含義是保留Filter原有的init和destory方法的調(diào)用。
3. Spring配置文件
3.1 配置詳解
3.1.1. shiro主過濾器
[費(fèi)有特][陳][帶神你神子]
常用的權(quán)限控制:
- anno:任何人都可以訪問;
- authc:必須登錄之后才能訪問,不包括remember me(記住密碼);
- user:登錄用戶才可以訪問,包含remember me(記住密碼);
- perm:過濾[權(quán)限]規(guī)則,這個(gè)一般擴(kuò)展使用(使用自定義過濾器,從數(shù)據(jù)庫(kù)查詢用戶權(quán)限),不會(huì)使用原生的。
- roles:過濾[角色]規(guī)則,這個(gè)一般擴(kuò)展使用,不會(huì)使用原生的。
攔截器優(yōu)先級(jí):
從上到下,從左到右,如果有匹配的攔截器就會(huì)阻斷并返回,例如訪問js/a.js,第一個(gè)攔截器anon符合,就返回true了,不在往下進(jìn)行匹配了。注意最后一個(gè)攔截最后一句是 /**=user意思就是除了上面的那些,其他的所有都要經(jīng)過。
<!-- Shiro主過濾器本身功能十分強(qiáng)大,其強(qiáng)大之處就在于它支持任何基于URL路徑表達(dá)式的、自定義的過濾器的執(zhí)行 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!--shiro的核心安全接口,這是屬性是必須的-->
<property name="securityManager" ref="securityManager"/>
<!-- 要求登錄時(shí)的鏈接,非必須的屬性,默認(rèn)會(huì)自動(dòng)尋找Web工程根目錄下的"/login.jsp"頁(yè)面 -->
<property name="loginUrl" value="/login/init"></property>
<!-- 用戶訪問未對(duì)其授權(quán)的資源時(shí),所顯示的連接 -->
<property name="unauthorizedUrl" value="/pages/error/403.jsp"/>
<!--定義過濾器鏈-->
<property name="filterChainDefinitions">
<value>
<!--Shiro過濾器鏈的配置-->
/login/init/** = anon <!-- 對(duì)于登錄相關(guān)不進(jìn)行鑒權(quán) -->
/static/** = anon <!-- 靜態(tài)資源不進(jìn)行鑒權(quán) -->
/** = user
</value>
</property>
<property name="filters">
<map>
<entry key="user" value-ref="userFilter"></entry>
</map>
</property>
</bean>
<!--自定義攔截器-->
<bean id="userFilter" class="com.springmvc.common.filter.SystemUserFilter"/>
3.1.2. 配置securityManager
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--作用:授權(quán)認(rèn)證,此處為單個(gè)realm,若想配置多個(gè),可使用realms參數(shù)-->
<property name="realm" ref="myRealm"/>
<!--設(shè)置會(huì)話模式(已過期),需配置適當(dāng)?shù)腤ebSessionManager實(shí)例-->
<property name="sessionMode" value="http"/>
<!--建議關(guān)閉,配合/**=user使用時(shí),可未經(jīng)授權(quán)登錄系統(tǒng)-->
<property name="rememberMeManager" ref="rememberMeManager"/>
<!--配置會(huì)話管理器-->
<property name="sessionManager" ref="defaultWebSessionManager"/>
</bean>
DefaultWebSecurityManager類主要定義了設(shè)置subjectDao,獲取會(huì)話模式,設(shè)置會(huì)話模式,設(shè)置會(huì)話管理器,是否http會(huì)話模式等操作。
3.1.3 配置remeberManager
java shiro配置記住密碼功能 RememberMe功能怎么實(shí)現(xiàn)
Shiro的 rememberMe 功能使用指導(dǎo)(為什么rememberMe設(shè)置了沒作用?)
<!-- remenberMe配置 -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe" />
<!-- 瀏覽器中通過document.cookie可以獲取cookie屬性,設(shè)置了HttpOnly=true,在腳本中就不能的到cookie,可以避免cookie被盜用 -->
<property name="httpOnly" value="true" />
<!-- 默認(rèn)記住7天(單位:秒) -->
<property name="maxAge" value="604800" />
</bean>
<!-- rememberMe管理器 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}" />
<property name="cookie" ref="rememberMeCookie" />
</bean>
注:Shiro主過濾器要使用/** = user。
3.1.4Realm配置
AuthorizingRealm為自定義Realm的父類,該類采用的模板方法模式,提供了2個(gè)方法供我們實(shí)現(xiàn)。
shiro(5)-有狀態(tài)認(rèn)證-Realm認(rèn)證的實(shí)現(xiàn)
- Authentication
[噢繁體kei神]認(rèn)證; - Authorization
[額死亂賊神]授權(quán);
<bean id="myRealm" class="com.springmvc.common.shiro.UserAuthorizingRealm"></bean>
3.1.5 sessionManager配置
DefaultWebSessionManager類主要定義了session的創(chuàng)建,啟動(dòng),暫停與cookie的關(guān)聯(lián)定義。
<bean id="defaultWebSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!--全局session過期時(shí)間:30分鐘操作會(huì)覆蓋web.xml文件中的超時(shí)時(shí)間配置 -->
<property name="globalSessionTimeout" value="1800000"/>
<!---session保存到redis中-->
<property name="sessionDAO" ref="customShiroSessionDAO"/>
<!-- 所有的session一定要將id設(shè)置到Cookie之中,需要提供有Cookie的操作模版 -->
<property name="sessionIdCookie" ref="simpleCookie"/>
<!--定時(shí)掃描超時(shí)session-->
<!-- session 監(jiān)聽,可以多個(gè)。 -->
<property name="sessionListeners">
<list>
<ref bean="customSessionListener"/>
</list>
</property>
<!--session關(guān)閉調(diào)度器-->
<property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>
<!-- 需要讓此session可以使用該定時(shí)調(diào)度器進(jìn)行檢測(cè) -->
<property name="sessionValidationSchedulerEnabled" value="true"/>
<!--刪除過期的session-->
<property name="deleteInvalidSessions" value="true"/>
</bean>
<!--自定義cookie的SessionId-->
<bean id="simpleCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg index="0" value="JSESSIONID_COOKIE"/>
<property name="httpOnly" value="true"/>
</bean>
<!--自定義session監(jiān)聽器-->
<bean id="customSessionListener" class="om.springmvc.common.filter.CustomSessionListener">
<property name="shiroSessionRepository" ref="jedisShiroSessionRepository"/>
</bean>
自定義sessionListener:
public class CustomSessionListener implements SessionListener {
public void onStart(Session session) {
}
public void onStop(Session session) {
}
public void onExpiration(Session session) {
}
}
3. 代碼中的使用
@Controller
@RequestMapping("/login")
public class LoginAction {
@RequestMapping(value = {"/init"})
public ModelAndView init() {
ModelAndView mv = new ModelAndView("login");
return mv;
}
@RequestMapping("/login")
public String login(@Param("username") String username,@Param("password") String password) {
try {
//創(chuàng)建token
UsernamePasswordToken token = new UsernamePasswordToken();
token.setUsername(username);
token.setPassword(password.toCharArray());
token.setRememberMe(true);
//調(diào)用驗(yàn)證
Subject subject = SecurityUtils.getSubject();
subject.login(token);
//驗(yàn)證是否登錄
if(subject.isAuthenticated()){
Session session=subject.getSession();
//整合redis設(shè)置session超時(shí)時(shí)間setex(sessionId,30*60);
//返回到頁(yè)面
return "redirect:/user";
}
} catch (UnknownAccountException e) {
//無(wú)用戶名
}catch (LockedAccountException e){
//密碼沒找到
}catch (IncorrectCredentialsException e){
//密碼不匹配
}catch (AuthenticationException e){
//其他登錄錯(cuò)誤
}catch (Exception e){
//未知異常
}
return "/error/403";
}
}