http://www.jianshu.com/p/6786ddf54582
参照此篇文章进行设置,此篇文章介绍了一个基本的shiro进行身份验证和权限验证的方法,实测可用,写这篇博客的目的为了复习自己配置shiro的基本流程
首先我们要有一个ssm maven项目,搭建ssm项目参照之前的博客
1.加入pom.xml
http://mvnrepository.com/ maven仓库的地址
<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>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-ehcache -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.2.3</version>
</dependency>
2.shiro配置文件配置
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"
>
<!-- 继承自AuthorizingRealm的自定义Realm,即指定Shiro验证用户登录的类为自定义的ShiroDbRealm.java -->
<bean id="myRealm" class="com.pack.shiro.ShiroManager"/>
<!-- Shiro默认会使用Servlet容器的Session,可通过sessionMode属性来指定使用Shiro原生Session -->
<!-- 即<property name="sessionMode" value="native"/>,详细说明见官方文档 -->
<!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
</bean>
<!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 -->
<!-- Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,Shiro对基于Spring的Web应用提供了完美的支持 -->
<bean id="shiroFilter" name="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager"/>
<!-- 要求登录时的链接(可根据项目的URL进行替换),非必须的属性,默认会自动寻找Web工程根目录下的"/login.jsp"页面 -->
<property name="loginUrl" value="/"/>
<!-- 登录成功后要跳转的连接(本例中此属性用不到,因为登录成功后的处理逻辑在LoginController里硬编码为main.jsp了) -->
<!-- <property name="successUrl" value="/system/main"/> -->
<!-- 用户访问未对其授权的资源时,所显示的连接 -->
<!-- 若想更明显的测试此属性可以修改它的值,如unauthor.jsp,然后用[玄玉]登录后访问/admin/listUser.jsp就看见浏览器会显示unauthor.jsp -->
<property name="unauthorizedUrl" value="/"/>
<!-- Shiro连接约束配置,即过滤链的定义 -->
<!-- 此处可配合我的这篇文章来理解各个过滤连的作用http://blog.csdn.net/jadyer/article/details/12172839 -->
<!-- 下面value值的第一个'/'代表的路径是相对于HttpServletRequest.getContextPath()的值来的 -->
<!-- anon:它对应的过滤器里面是空的,什么都没做,这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 -->
<!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->
<property name="filterChainDefinitions">
<value>
<!-- anon表示此地址不需要任何权限即可访问 -->
/static/**=anon
<!-- perms[user:query]表示访问此连接需要权限为user:query的用户 -->
<!--/user=perms[user:query]-->
<!-- roles[manager]表示访问此连接需要用户的角色为manager -->
<!--/user/add=roles[manager]-->
<!--所有的请求(除去配置的静态资源请求或请求地址为anon的请求)都要通过登录验证,如果未登录则跳到/login-->
/** = authc
</value>
</property>
</bean>
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 -->
<!-- 配置以下两个bean即可实现此功能 -->
<!-- Enable Shiro Annotations for Spring-configured beans. Only run after the lifecycleBeanProcessor has run -->
<bean class="org.apache.shiro.spring.security.intrceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
</beans>
3.在mybatis配置文件中进行配置
<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
">
<!-- 自动扫描 -->
<context:component-scan base-package="com.pack"><!-- base-package 如果多个,用“,”分隔 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 引入配置文件 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</bean>
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:mapping/*.xml"></property>
</bean>
<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.pack.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
<!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- 配置自定义Realm -->
<bean id="myRealm" class="com.pack.shiro.ShiroManager"/>
<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="myRealm"/>
</bean>
<!-- Shiro过滤器 核心-->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager"/>
<!-- 身份认证失败,则跳转到登录页面的配置 -->
<property name="loginUrl" value="/login"/>
<!-- 权限认证失败,则跳转到指定页面 -->
<property name="unauthorizedUrl" value="/angular.jsp"/>
<!-- Shiro连接约束配置,即过滤链的定义 -->
<property name="filterChainDefinitions">
<value>
<!--anon 表示匿名访问,不需要认证以及授权-->
/loginAdmin=anon
<!--authc表示需要认证 没有进行身份认证是不能进行访问的-->
/admin*=authc
/student=roles[teacher]
/teacher=perms["user:create"]
</value>
</property>
</bean>
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- 开启Shiro注解 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true"/>
</bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"/>
</bean>
<!-- remenberMe配置 -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe" />
<property name="httpOnly" value="true" />
<!-- 默认记住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>
</beans>
4.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"
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>Archetype Created Web Application</display-name>
<!-- Spring和mybatis的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mybatis.xml</param-value>
</context-param>
<!-- 编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- shiro过滤器定义 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->
<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>
<!-- Spring监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 防止Spring内存溢出监听器 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- Spring MVC servlet -->
<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:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- 此处可以可以配置成*.do,对应struts的后缀习惯 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<session-config>
<session-timeout>15</session-timeout>
</session-config>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
</web-app>
5.spring-mvc配置
<?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/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
"
>
<!-- Spring MVC所扫描的路径 -->
<context:component-scan base-package="com.pack" use-default-filters="false"><!-- base-package 如果多个,用“,”分隔 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--避免IE执行AJAX时,返回JSON出现下载文件 -->
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<!--<mvc:interceptors>-->
<!--<mvc:interceptor>-->
<!--<mvc:mapping path="/**"/>-->
<!--<mvc:exclude-mapping path="/user/loginsc"/>-->
<!--<mvc:exclude-mapping path="/user/logout"/>-->
<!--<mvc:exclude-mapping path="/styles/**"/>-->
<!--<mvc:exclude-mapping path="/scripts/**"/>-->
<!--<mvc:exclude-mapping path="/images/**"/>-->
<!--<bean id="loginInterceptor" class="com.you.interceptor.LoginInterceptor"/>-->
<!--</mvc:interceptor>-->
<!--</mvc:interceptors>-->
<!-- 定义无Controller的path<->view直接映射 -->
<!--<mvc:view-controller path="/" view-name="redirect:/user/first"/>-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!--静态资源映射-->
<mvc:resources mapping="/static/**" location="/static/" />
<!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON转换器 -->
</list>
</property>
</bean>
<!-- 定义跳转的文件的前后缀 ,视图模式配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 默认编码 -->
<property name="defaultEncoding" value="utf-8" />
<!-- 文件大小最大值 -->
<property name="maxUploadSize" value="10485760000" />
<!-- 内存中的最大值 -->
<property name="maxInMemorySize" value="40960" />
</bean>
<!--此配置一定要在spingmvc的配置文件中进行配置-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.apache.shiro.authz.UnauthorizedException">error/403</prop>
<prop key="java.lang.Throwable">error/500</prop>
</props>
</property>
</bean>
</beans>
6.建立登录页面
这里使用了bootstrap以及一个生成svg图像的插件trianglify,以及弹出框的layer
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" import="java.util.*"%>
<%@ include file="/WEB-INF/include/taglib.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=request.getContextPath()%>/" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>登录</title>
<%@ include file="/WEB-INF/include/header.jsp"%>
<style>
</style>
</head>
<body>
<div class="container">
<form role="form" class="col-md-4 center-block" style="margin:120px auto 0 auto;float:none">
<div class="form-group">
<label for="name">用户名</label>
<input type="text" class="form-control" id="name" placeholder="Enter userName" style="padding:20px;">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control" id="password" placeholder="Password" style="padding:20px;">
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="che"> 记住密码
</label>
</div>
<div class="col-md-12" style="padding:0px;">
<button type="button" class="btn btn-default btn-block" id="sub" style="padding:10px;">Sign in</button>
</div>
<div id="wordsShow" style="padding-top:20px;text-align: center;"> </div>
</form>
</div>
</body>
<script type="text/javascript">
var h = window.innerHeight, w = window.innerWidth;
// set up the base pattern
var pattern = Trianglify({
height: h,
width: w,
cell_size: 30 + Math.random() * 50});
// png
var png = document.createElement('img');
$("body")[0].background=pattern.png();
$("#sub").click(function(){
var name = $("#name").val();
var password = $("#password").val();
$.get("/user/login",{name:name,password:password},function (text) {
if(text==="2"){
layer.alert('用户名或密码错误', {
skin: 'layui-layer-lan'
,closeBtn: 0
,anim: 4 //动画类型
});
}else{
window.location.href="/user/tree";
}
});
})
var msgArr = ["有事做有所期待,日子就是幸福的。",
"生活如此难,要怎么过?一笑而过。",
"碧波荡漾一抹香,茶不醉人人自醉。",
"只要把心放宽,快乐其实很简单。",
"生活不能等待别人来安排,要自己去争取与奋斗!",
"每天都应该是有收获的,哪怕只是一句话。",
"只要路是对的,就不怕路远。",
"开心了就笑,不开心就过会再笑。",
"生活的小处,总是藏有大观。",
"总有一种期待,是家的味道。",
"学会在浮躁中思考,你才知道在喧嚣中走向哪里。",
"万家灯火中,总有一盏为你点亮。",
"有时候、宁愿像个孩子,不肯看太多的事,听太多的不是,单纯的过一辈子多好!",
"用心每一天,不忘初心,方能走远。",
"即使没有翅膀,心也要飞翔。",
"积一时之跬步,臻千里之遥程。",
"不开心时,记得要让心情转个弯。",
"偷偷挤进的一缕斜阳,送来满满的幸福。",
"只要坚持,事情再小也挡不住宏大的梦。",
"优等的心,不必华丽,但必须坚固。",
"天再高,踮起脚尖就能更接近阳光!",
"与未知的相遇,七分欢喜三分孤寂。",
"有事做有所期待,日子就是幸福的。",
"天时人事日相催,冬至阳生春又来",
"一串淡然的心情,一份纯粹的快乐。",
"我不要做普通人。"
];
var index = parseInt(Math.random() * (msgArr.length - 1));
var currentMsg = msgArr[index];
$("#wordsShow").html(currentMsg);
</script>
</html>
7.数据库结构,用户表,权限表,角色表
CREATE TABLE `user` (
`id` VARCHAR(64) NOT NULL PRIMARY KEY,
`name` VARCHAR(20) DEFAULT NULL,
`password` VARCHAR(20) DEFAULT NULL,
`role_Id` INT(11) DEFAULT NULL,
`CREATE_BY` VARCHAR(64) DEFAULT NULL,
`CREATE_DATE` DATETIME(6) DEFAULT NULL,
`UPDATE_BY` VARCHAR(64) DEFAULT NULL,
`UPDATE_DATE` DATETIME(6) DEFAULT NULL,
`REMARKS` VARCHAR(255) DEFAULT NULL,
`DEL_FLAG` CHAR(1) NOT NULL,
KEY `id` (`id`)
) ENGINE=INNODB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
CREATE TABLE `permission` (
id int(11) NOT NULL AUTO_INCREMENT,
`permission_name` varchar(50) DEFAULT NULL,
`roleId` int(11) DEFAULT NULL,
`CREATE_BY` VARCHAR(64) DEFAULT NULL,
`CREATE_DATE` DATETIME(6) DEFAULT NULL,
`UPDATE_BY` VARCHAR(64) DEFAULT NULL,
`UPDATE_DATE` DATETIME(6) DEFAULT NULL,
`REMARKS` VARCHAR(255) DEFAULT NULL,
`DEL_FLAG` CHAR(1) NOT NULL,
KEY `id` (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `role` (
`id` int(11) DEFAULT NULL AUTO_INCREMENT ,
`role_name` varchar(50) DEFAULT NULL,
`CREATE_BY` VARCHAR(64) DEFAULT NULL,
`CREATE_DATE` DATETIME(6) DEFAULT NULL,
`UPDATE_BY` VARCHAR(64) DEFAULT NULL,
`UPDATE_DATE` DATETIME(6) DEFAULT NULL,
`REMARKS` VARCHAR(255) DEFAULT NULL,
`DEL_FLAG` CHAR(1) NOT NULL,
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `user` (`id`, `name`, `password`, `role_Id`, `CREATE_BY`, `CREATE_DATE`, `UPDATE_BY`, `UPDATE_DATE`, `REMARKS`, `DEL_FLAG`) VALUES('1','123','123','1','1','2018-07-20 09:45:04.000000','1','2018-07-20 09:45:09.000000',NULL,'0');
INSERT INTO `user` (`id`, `name`, `password`, `role_Id`, `CREATE_BY`, `CREATE_DATE`, `UPDATE_BY`, `UPDATE_DATE`, `REMARKS`, `DEL_FLAG`) VALUES('2','456','456','2','1','2018-07-20 09:45:22.000000','1','2018-07-20 09:45:27.000000',NULL,'0');
INSERT INTO `role` (`id`, `role_name`, `CREATE_BY`, `CREATE_DATE`, `UPDATE_BY`, `UPDATE_DATE`, `REMARKS`, `DEL_FLAG`) VALUES('1','admin','1','2018-07-20 09:46:37.000000','1','2018-07-20 09:46:40.000000',NULL,'0');
INSERT INTO `role` (`id`, `role_name`, `CREATE_BY`, `CREATE_DATE`, `UPDATE_BY`, `UPDATE_DATE`, `REMARKS`, `DEL_FLAG`) VALUES('2','teacher','1','2018-07-20 09:46:59.000000','1','2018-07-20 09:47:01.000000',NULL,'0');
INSERT INTO `permission` (`id`, `permission_name`, `role_id`, `CREATE_BY`, `CREATE_DATE`, `UPDATE_BY`, `UPDATE_DATE`, `REMARKS`, `DEL_FLAG`) VALUES('1','teacher','1','1','2018-07-20 09:47:26.000000','1','2018-07-20 09:47:30.000000',NULL,'0');
INSERT INTO `permission` (`id`, `permission_name`, `role_id`, `CREATE_BY`, `CREATE_DATE`, `UPDATE_BY`, `UPDATE_DATE`, `REMARKS`, `DEL_FLAG`) VALUES('2','student','2','1','2018-07-20 09:47:46.000000','1','2018-07-20 09:47:51.000000',NULL,'0');
8.建立service,implement,dao,mapper
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.pack.dao.UserDao" >
<sql id="Base_Column_List" >
a.id,
a.name,
a.password,
a.role_id AS "roleId",
a.create_by AS "createBy.id",
a.create_date AS "createDate",
a.update_by AS "updateBy.id",
a.update_date AS "updateDate",
a.del_flag AS "delFlag"
</sql>
<select id="get" resultType="com.pack.bean.User">
select
<include refid="Base_Column_List"/>
from `user`
where id = #{id}
</select>
<select id="findList" resultType="com.pack.bean.User" >
SELECT
<include refid="Base_Column_List"/>
FROM `user` a
<where>
<if test="name !=null and name !=''">
AND a.name= #{name}
</if>
<if test="password !=null and password !=''">
AND a.password = #{password}
</if>
</where>
</select>
<select id="findPermissionList" resultType="com.pack.bean.User">
SELECT p.permission_name AS "permissionName"
FROM user a
LEFT JOIN role r ON a.role_id=r.id
LEFT JOIN permission p ON p.role_id = r.id
<where>
<if test="name !=null and name !=''">
AND a.name= #{name}
</if>
</where>
</select>
<select id="findRoleList" resultType="com.pack.bean.User">
SELECT r.role_name AS "roleName"
FROM user a
LEFT JOIN role r ON a.role_id=r.id
<where>
<if test="name !=null and name !=''">
AND a.name= #{name}
</if>
</where>
</select>
</mapper>
9.拦截类
@Service
public class ShiroManager extends AuthorizingRealm {
//依赖注入
@Autowired
private UserService userService ;
//权限认证
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("jinru");
String username = principalCollection.getPrimaryPrincipal().toString();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
System.out.println(username+"===============");
//获取权限信息
List<User> users = userService.findPermissionList(new User(username));
if(BpmUtils.listIsNull(users)){
for (User user : users) {
info.addStringPermission(user.getPermissionName());
System.out.println(user.getPermissionName()+"------------------");
}
}
//获取角色信息
List<User> userList = userService.findRoleList(new User(username));
if(BpmUtils.listIsNull(userList)){
for (User user : userList) {
info.addRole(user.getRoleName());
System.out.println(user.getRoleName()+"------------------");
}
}
return info;
}
//登录认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("首先进入");
String username = authenticationToken.getPrincipal().toString();
String password = new String((char[])authenticationToken.getCredentials());
System.out.println(username+"----------"+password);
User user = new User();
user.setName(username);
user.setPassword(password);
List<User> us = userService.findList(user);
if(us!=null){
AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getName(),user.getPassword(),
"a") ;
return authenticationInfo ;
}else{
return null;
}
}
}