Apache Shiro 是java的一個安全框架。它能夠幫助我們完成:認證、授權、加密、會話管理、與web集成、緩存等。使用Shiro的易於理解的API,您可以快速、輕松地獲得任何應用程序,從最小的移動應用程序到最大的網絡和企業應用程序。
首先我們看一下shiro的系統框架:
從上圖可以看出,shiro框架包含了以下主題內容:
下面,我們就通過集成spring項目配置學習shiro
首先,我們要新建一個spring項目,我的項目框架完成時是這樣的:
在pom.xml 中添加依賴:
<properties> <org.springframework.version>4.2.4.RELEASE</org.springframework.version> </properties> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.16</version> </dependency> <!--servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <!--spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> </dependency> <!-- druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.14</version> </dependency> <!-- aspectj --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.7.4</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.4</version> </dependency> <!-- cglib --> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.1</version> </dependency> <!--日志--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- jstl --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- standard --> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <!--shiro--> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>2.6.8</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-quartz</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.2</version> </dependency> </dependencies>
以上主要添加的依賴是:spring支持依賴、severlet支持依賴、durid支持依賴、aspectj支持依賴、cglib支持依賴、jstl支持依賴、日志依賴、shiro依賴。
在web.xml中配置過濾器:
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--編碼過濾器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置StrutsPrepareAndExecuteFilter之前-->
<!-- 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>
</web-app>
web.xml中主要是配置springmvc,引入中央處理器DispatcherServlet,初始化時加載mvc.xml配置文件;還配置了編碼過濾器,統一字符集;然后就是最重要的shiro過濾器了。mvc.xml配置文件如下:
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:mvc="http://www.springframework.org/schema/mvc" 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.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--1:配置DI注解解析器--> <context:annotation-config/> <!--2:配置IoC注解解析器--> <context:component-scan base-package="cn.wolfcode.shiro"/> <!--3:配置mvc注解解析器--> <mvc:annotation-driven/> <!--4:靜態資源處理--> <mvc:default-servlet-handler/> <!--5:配置視圖解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> <!--6:引入shiro配置文件--> <import resource="classpath:spring-shiro.xml"></import> <!--7:引入spring配置文件--> <import resource="classpath:spring.xml"></import> </beans>
其中cn.wolfcode.shiro是shiro的掃描包,spring-shiro.xml配置文件如下:
<?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:aop="http://www.springframework.org/schema/aop" xmlns:url="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <!--配置自定義的realm值--> <bean id="userRealm" class="cn.wolfcode.shiro.realm.UserRealm"> <!--密碼需要加密,加密器--> <property name="credentialsMatcher" ref="credentialsMatcher" /> <property name="userDAO" ref="userDAOImpl"></property> <property name="roleDAO" ref="roleDAOImpl"></property> <property name="permissionDAO" ref="permissionDAOImpl"></property> </bean> <!-- 配置安全管理器SecurityManager --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="userRealm"/> <property name="cacheManager" ref="cacheManager"></property> </bean> <!--自定義Filter--> <bean id="myFormAuthenticationFilter" class="cn.wolfcode.shiro.realm.FormAuthentication"/> <!--注意:名字必須要和web.xml中配置的名字一致--> <!-- 定義ShiroFilter --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <property name="loginUrl" value="/login"/> <property name="unauthorizedUrl" value="/nopermission.jsp"/> <property name="successUrl" value="/main"/> <property name="filters"> <url:map> <entry key="authc" value-ref="myFormAuthenticationFilter"/> </url:map> </property> <property name="filterChainDefinitions"> <value>
<!--退出過濾器--> /logout=logout /**=authc </value> </property> </bean> <!--在總的applicationContext.xml中添加如下配置:--> <!-- 開啟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> <!--在需要控制的方法上貼上注解:@RequiresPermissions("employee:view")--> <!-- 定義需要特殊處理的異常,用類名或完全路徑名作為key,異常頁名作為值 --> <!--shiro權限異常處理--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthorizedException">redirect:/nopermission.jsp</prop> </props> </property> </bean> <!--如果導入的ehcache版本在2.5.0以上,需要配置如下.--> <!-- 緩存管理器開始 --> <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManager" ref="ehCacheManager"/> </bean> <bean id="ehCacheManager" class ="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:shiro-ehcache.xml" /> <property name="shared" value="true"></property> </bean> <!--加密器--> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <!--加密算法--> <property name="hashAlgorithmName" value="md5" /> <!--散列次數--> <property name="hashIterations" value="3" /> </bean> </beans>
這是shiro的核心配置,主要是注入自定義的realm(可以理解為是從數據庫查出來的users包括用戶名、密碼、角色和權限),安全管理器SecurityManager ,自定義的filter(主要是讓用戶在登錄成功之后跳轉到/main頁面,如果不設置,用戶在登錄之后就會跳到上一次訪問的URL,如果我們是直接訪問登錄頁面的話,shiro就會根據我們配置的successUrl去重定向,如果我們沒有配置successUrl的話,那么shiro重定向默認的/,從而報404錯誤),shiroFilter(主要是配置登錄頁面,登錄成功后的跳轉頁面,以及沒有權限時跳轉到nopermission.jsp頁面),開啟aop,對類代理,開啟shiro注解支持,異常處理機制(當用戶當前無訪問權限的時候跳轉到nopermission.jsp頁面,而不是頁面顯示500),緩存管理機制(主要是用戶登錄之后不用再次進行認證授權操作,提高系統性能和效率)和加密器(shiro自身支持MD5和SHA加密算法,我這里配置的是md5,並且散列次數為3,相當於是加密了3次,還有加鹽的操作,只是加鹽不用在配置文件中提現,下面會講到)。
spring.xml配置文件如下:
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:mvc="http://www.springframework.org/schema/mvc" 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.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--1:引入數據源配置文件--> <context:property-placeholder location="classpath:jdbc.properties" system-properties-mode="NEVER"/> <!--2:配置數據源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> </beans>
主要是配置數據源,其中的jdbc.properties配置文件如下:
jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///shiro?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=UTF-8 jdbc.username=root jdbc.password=root
log4j.properties配置文件如下:
# Global logging configuration log4j.rootLogger=ERROR, stdout # MyBatis logging configuration... log4j.logger.cn.wolfcode.shiro=TRACE # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
shiro-ehcache.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <ehcache> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> </ehcache>
然后還有比較重要的就是UserRealm了,文件如下:
package cn.wolfcode.shiro.realm; import cn.wolfcode.shiro.dao.IPermissionDAO; import cn.wolfcode.shiro.dao.IRoleDAO; import cn.wolfcode.shiro.dao.IUserDAO; import cn.wolfcode.shiro.domain.User; import lombok.Setter; import org.apache.shiro.SecurityUtils; 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; import java.util.ArrayList; import java.util.List; /** * Created with IntelliJ IDEA. * User: gaopeng * Date: 2018/11/9 0009 * Time: 11:39 * Description: */ public class UserRealm extends AuthorizingRealm{ @Setter public IUserDAO userDAO; @Setter public IRoleDAO roleDAO; @Setter public IPermissionDAO permissionDAO; //獲取realmName @Override public String getName(){ return "userRealm"; } //授權 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { List<String> permission = new ArrayList<>(); List<String> roles = new ArrayList<>(); User user = (User) principalCollection.getPrimaryPrincipal(); if ("admin".equals(user.getUsername())) { permission.add("*:*"); roles = roleDAO.getAllRoleSn(); }else { permission.addAll(permissionDAO.getPermissionResourceByUserId(user.getId())); roles = roleDAO.getRoleSnByUserId(user.getId()); } SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addStringPermissions(permission); info.addRoles(roles); return info; } //認證 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { //從token中獲取登錄的用戶名,查詢數據庫返回的用戶信息 String userName = (String) authenticationToken.getPrincipal(); User user = userDAO.getUserByUsername(userName); if (user == null) { return null; } SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getUsername()), getName()); return info; } //清除緩存 public void clearCached() { //獲取當前登錄用戶的憑證,然后清除 PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals(); super.clearCache(principals); } }
這里面有4個方法其中授權和認證是shiro用戶登錄的核心,其登陸登出流程如下圖:
首先用戶登錄時從頁面傳來了登錄的用戶名和密碼,通過token對象傳到subject,subject調用login(token)方法將他自己和token作為參數委托SecurityManager進行登錄認證授權,而SecurityManager的功能和DeparterSeverlet類似(相當於是一個中央管理器),將從數據庫查詢出來的所有用戶名和密碼及token傳給認證器authenticator,認證器先是通過token(用戶傳過來的用戶名和密碼)獲取username,接着查realm中是否存在這樣的用戶名,如果不存在就返回null,此時認證不通過,返回到SecurityManager后報UnknownAccountException錯誤,controller處理這種錯誤,頁面跳轉到登錄頁面,如果存在 username則將查詢出來的用戶名密碼包裝成AuthenticationInfo對象,對比token中的密碼,如果一致,表示登錄成功,否則登錄失敗,報IncorrectCredentialsException錯誤,controller處理這種錯誤,頁面跳轉到登錄頁面。
注意:這里的SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getUsername()), getName());是把user.getUsername()作為鹽進行密碼加密的。
LoginController如下:
package cn.wolfcode.shiro.web.controller; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; @Controller public class LoginController { @RequestMapping("/login") public String login(Model model, HttpServletRequest req) throws Exception{ //如果登陸失敗從request中獲取認證異常信息,shiroLoginFailure就是shiro異常類的全限定名 String exceptionClassName = (String) req.getAttribute("shiroLoginFailure"); //根據shiro返回的異常類路徑判斷,拋出指定異常信息 if(exceptionClassName!=null){ if (UnknownAccountException.class.getName().equals(exceptionClassName)) { //最終會拋給異常處理器 model.addAttribute("errorMsg", "賬號不存在"); } else if (IncorrectCredentialsException.class.getName().equals( exceptionClassName)) { model.addAttribute("errorMsg", "用戶名/密碼錯誤"); } else { //最終在異常處理器生成未知錯誤. model.addAttribute("errorMsg", "其他異常信息"); } } //此方法不處理登陸成功(認證成功),shiro認證成功會自動跳轉到上一個請求路徑 //登陸失敗還到login頁面 return "forward:/login.jsp"; } }
shiro在頁面上展示時如果有權限限制,它本身是提供有shiro標簽的,如下:
要進行權限的認證,我在數據庫中創建了5張表,分別是user,user_role,role,role_permission,permission,其中的sql語句如下:
/* SQLyog Professional v12.09 (64 bit) MySQL - 5.5.28 : Database - shiro ********************************************************************* */ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=''*/; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; CREATE DATABASE /*!32312 IF NOT EXISTS*/`shiro` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `shiro`; /*Table structure for table `permission` */ DROP TABLE IF EXISTS `permission`; CREATE TABLE `permission` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `resource` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8; /*Data for the table `permission` */ insert into `permission`(`id`,`name`,`resource`) values (1,'員工保存','employee:save'),(2,'員工刪除','employee:delete'),(3,'員工列表','employee:list'),(4,'員工編輯','employee:edit'),(5,'部門保存','department:save'),(6,'部門列表','department:list'),(7,'部門刪除','department:delete'),(8,'部門編輯','department:edit'); /*Table structure for table `role` */ DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8 DEFAULT NULL, `sn` varchar(255) CHARACTER SET utf8 DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*Data for the table `role` */ insert into `role`(`id`,`name`,`sn`) values (1,'部門經理','deptMgr'),(2,'員工經理','empMgr'); /*Table structure for table `role_permission` */ DROP TABLE IF EXISTS `role_permission`; CREATE TABLE `role_permission` ( `role_id` bigint(20) NOT NULL, `permission_id` bigint(20) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*Data for the table `role_permission` */ insert into `role_permission`(`role_id`,`permission_id`) values (2,1),(2,2),(2,3),(2,4),(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8); /*Table structure for table `user` */ DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `username` varchar(255) CHARACTER SET utf8 DEFAULT NULL, `password` varchar(255) CHARACTER SET utf8 DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*Data for the table `user` */ insert into `user`(`id`,`username`,`password`) values (1,'admin','3fed7a346e430ea4c2aa10250928f4de'),(2,'zhangsan','cd757bae8bd31da92c6b14c235668091'); /*Table structure for table `user_role` */ DROP TABLE IF EXISTS `user_role`; CREATE TABLE `user_role` ( `user_id` bigint(20) NOT NULL, `role_id` bigint(20) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*Data for the table `user_role` */ insert into `user_role`(`user_id`,`role_id`) values (2,2); /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
其中user表中的賬號信息是:zhangsan:666;admin:admin,這里是因為加密了,密碼是看不出來的。
這些表的一些數據查詢接口,我這里就不一一展示了,源碼在下面:
https://download.csdn.net/download/weixin_38340967/10781371
我也是看了shiro視頻學習后,總結的這篇文章,視頻資源:https://ke.qq.com/course/289923,希望能對你有所幫助!謝謝!