一、基於xml配置的shiro整合SpringMVC
項目結構圖
所需要導入的包
1.Spring容器配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <context:component-scan base-package="cn.lch"/> </beans>
2.SpringMVC配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <!-- 打開注解驅動 --> <mvc:annotation-driven /> <!-- 放開靜態資源攔截 --> <mvc:default-servlet-handler/> <!-- 視圖解釋器 --> <mvc:view-resolvers> <mvc:jsp prefix="/WEB-INF/views/" suffix=".jsp"/> </mvc:view-resolvers> </beans>
3.Shiro整合Spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 第一步:指定Shiro的攔截過濾器 --> <bean name="shiroFilterBean" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 指定securityManager容器對象 --> <property name="securityManager" ref="securityManager"></property> <!-- 設置攔截器鏈 說明:Shiro提供了很多攔截器,用於不同場景的路徑攔截,我們就在攔截器鏈中設置攔截請求的場景 anon :指定不攔截的路徑,如登錄頁面請求 /user/toLogin = anon authc : 必須需要校驗的路徑 logout :注銷攔截器。如果路徑類型為logout就是一個注銷路徑 --> <property name="filterChainDefinitions"> <value> /user/toLogin = anon /logout = logout /** = authc </value> </property> <!-- 配置自定義攔截器 --> <!-- 指定登錄的請求路徑 --> <property name="loginUrl" value="/user/login" /> <!-- 指定登錄成功后跳轉的路徑 --> <property name="successUrl" value="/index" /> </bean> <!-- 第二步:創建securityManager對象 --> <bean name="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realms" ref="shiroRealm"></property> </bean> <!-- 第三步:創建自定義realm對象 --> <bean name="shiroRealm" class="cn.lch.realm.ShiroRealm"> <property name="credentialsMatcher"> <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="md5"></property> <property name="hashIterations" value="1"></property> </bean> </property> </bean> </beans>
4.shiroRealm的配置
package cn.lch.realm; import java.util.HashMap; import java.util.Map; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; public class ShiroRealm extends AuthorizingRealm{ /** * 用於權限校驗的方法 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("-權限校驗-"); if ("admin".equals(token.getPrincipal())) { Map<String, Object> user=new HashMap<>(); user.put("user_name", "admin"); user.put("user_password", "879b208f9aa10d8a87d93c77b89419bc"); user.put("user_id", 1); ByteSource salt = ByteSource.Util.bytes("abcd123"); return new SimpleAuthenticationInfo(user,user.get("user_password"),salt,this.getName()); } return null; } /** * 用於權限授予的方法 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); info.addRole("role_admin"); info.addStringPermission("user:add"); info.addStringPermission("user:list"); return info; } }
5.跳轉頁面的配置
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <!-- 如果通過了校驗,跳轉到首頁 --> <shiro:authenticated> <jsp:forward page="/index"></jsp:forward> </shiro:authenticated> <!-- 如果不通過了校驗,跳轉到登錄頁面--> <shiro:notAuthenticated> <jsp:forward page="/user/toLogin"></jsp:forward> </shiro:notAuthenticated> </body> </html>
6.Controller層的處理代碼
package cn.lch.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class IndexController { @RequestMapping(value="/index") public String toIndex() { return "index"; } }
package cn.lch.controller; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.annotation.SessionScope; @Controller @SessionScope @RequestMapping(value="/user") public class UserController { @RequestMapping(value = "/toLogin") public String toLogin() { System.out.println("跳轉到用戶登錄"); return "login"; } @RequestMapping(value = "/login") public String login(HttpServletRequest request) { System.out.println("用戶登錄"); //需求:登錄失敗要返回出現信息 Object shiroLoginFailure = request.getAttribute("shiroLoginFailure"); System.out.println(shiroLoginFailure); if("org.apache.shiro.authc.UnknownAccountException".equals(shiroLoginFailure)) { request.setAttribute("user_login_msg", "用戶名錯誤"); }else if ("org.apache.shiro.authc.IncorrectCredentialsException".equals(shiroLoginFailure)) { request.setAttribute("user_login_msg", "密碼錯誤"); } return "login"; } }
7.登錄頁面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/user/login" method="post"> ${requestScope.user_login_msg }<br/> 用戶名:<input name="username" type="text"><br/> 密碼:<input name="password" type="password"><br/> <input type="submit" value="登錄"> </form> </body> </html>
8.主頁
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> 主頁 <a href="${pageContext.request.contextPath }/logout">退出</a><br/> <shiro:hasPermission name="user:list"> <!-- 如果有user:list權限才顯示 用戶列表 --> <a href="#"> 用戶列表</a><br/> </shiro:hasPermission> <shiro:hasPermission name="user:add"> <!-- 如果有user:add權限才顯示 用戶增加 --> <a href="#"> 用戶增加</a><br/> </shiro:hasPermission> <shiro:hasPermission name="user:edit"> <!-- 如果有user:edit權限才顯示 用戶編輯 --> <a href="#"> 用戶編輯</a><br/> </shiro:hasPermission> </body> </html>
運行結果(從跳轉頁面index.xml運行)