ApacheShiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理
如同Springsecurity一样都是是一个权限安全框架,但是与SpringSecurity相比,在于他使用了和比较简洁易懂的认证和授权方式。
1、Subject:当前用户的操作
2、SecurityManager:用于管理所有的Subject
3、Realms:用于进行权限信息的验证
Subject:即当前用户,在权限管理的应用程序里往往需要知道谁能够操作什么,谁拥有操作该程序的权利,shiro中则需要通过Subject来提供基础的当前用户信息,Subject不仅仅代表某个用户,也可以是第三方进程、后台帐户(DaemonAccount)或其他类似事物。
SecurityManager:即所有Subject的管理者,这是Shiro框架的核心组件,可以把他看做是一个Shiro框架的全局管理组件,用于调度各种Shiro框架的服务。
Realms:Realms则是用户的信息认证器和用户的权限人证器,我们需要自己来实现Realms来自定义的管理我们自己系统内部的权限规则。
在shiro的用户权限认证过程中其通过两个方法来实现:
1、Authentication:是验证用户身份的过程。
2、Authorization:是授权访问控制,用于对用户进行的操作进行人证授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等。
除了以上几个组件外,Shiro还有几个其他组件:
1、SessionManager:Shiro为任何应用提供了一个会话编程范式。
2、CacheManager:对Shiro的其他组件提供缓存支持。
图片转自:http://kdboy.iteye.com/blog/1154644
持久层框架:Hibernate4这边我使用了Hibernate来对数据持久层进行操作
控制显示层框架:SpringMVC这边我使用了SpringMVC实际开发中也可以是其他框架
数据库:MySql
准备好所需要的jar放到项目中。
首先需要四张表,分别为user(用户)、role(角色)、permission(权限)、userRole(用户角色关系表)
这边分别创建四张表的实体类,通过Hiberante的hibernate.hbm2ddl.auto属性的update来自动生成数据表结构。
用户表:
1packagecom.ssh.entity; 2 3importjava.util.Date; 4importjava.util.List; 5 6importjavax.persistence.CascadeType; 7importjavax.persistence.Entity; 8importjavax.persistence.GeneratedValue; 9importjavax.persistence.GenerationType; 10importjavax.persistence.Id; 11importjavax.persistence.OneToMany; 12importjavax.persistence.Table; 13 14@Table(name="t_user") 15@Entity 16publicclassUser{ 17 18@Id 19@GeneratedValue(strategy=GenerationType.AUTO) 20Integerid; 21 22Stringusername; 23Stringpassword; 24IntegerisDelete; 25DatecreateDate; 26@OneToMany(mappedBy="user",cascade=CascadeType.ALL) 27List<UserRole>userRoles; 28publicIntegergetId(){ 29returnid; 30} 31publicvoidsetId(Integerid){ 32this.id=id; 33} 34publicStringgetUsername(){ 35returnusername; 36} 37publicvoidsetUsername(Stringusername){ 38this.username=username; 39} 40publicStringgetPassword(){ 41returnpassword; 42} 43publicvoidsetPassword(Stringpassword){ 44this.password=password; 45} 46publicIntegergetIsDelete(){ 47returnisDelete; 48} 49publicvoidsetIsDelete(IntegerisDelete){ 50this.isDelete=isDelete; 51} 52publicDategetCreateDate(){ 53returncreateDate; 54} 55publicvoidsetCreateDate(DatecreateDate){ 56this.createDate=createDate; 57} 58publicList<UserRole>getUserRoles(){ 59returnuserRoles; 60} 61publicvoidsetUserRoles(List<UserRole>userRoles){ 62this.userRoles=userRoles; 63} 64 65 66}角色表:
1packagecom.ssh.entity; 2 3importjavax.persistence.Entity; 4importjavax.persistence.GeneratedValue; 5importjavax.persistence.GenerationType; 6importjavax.persistence.Id; 7importjavax.persistence.Table; 8 9@Entity 10@Table(name="t_role") 11publicclassRole{ 12 13@Id 14@GeneratedValue(strategy=GenerationType.AUTO) 15Integerid; 16Stringname; 17Stringdescription; 18publicIntegergetId(){ 19returnid; 20} 21publicvoidsetId(Integerid){ 22this.id=id; 23} 24publicStringgetName(){ 25returnname; 26} 27publicvoidsetName(Stringname){ 28this.name=name; 29} 30publicStringgetDescription(){ 31returndescription; 32} 33publicvoidsetDescription(Stringdescription){ 34this.description=description; 35} 36 37}权限表:
1packagecom.ssh.entity; 2 3importjavax.persistence.Entity; 4importjavax.persistence.GeneratedValue; 5importjavax.persistence.GenerationType; 6importjavax.persistence.Id; 7importjavax.persistence.Table; 8 9@Entity 10@Table(name="t_permission") 11publicclassPermission{ 12 13@Id 14@GeneratedValue(strategy=GenerationType.AUTO) 15Integerid; 16/**token**/ 17Stringtoken; 18/**资源url**/ 19Stringurl; 20/**权限说明**/ 21Stringdescription; 22/**所属角色编号**/ 23IntegerroleId; 24publicIntegergetId(){ 25returnid; 26} 27publicvoidsetId(Integerid){ 28this.id=id; 29} 30publicStringgetToken(){ 31returntoken; 32} 33publicvoidsetToken(Stringtoken){ 34this.token=token; 35} 36publicStringgetUrl(){ 37returnurl; 38} 39publicvoidsetUrl(Stringurl){ 40this.url=url; 41} 42publicStringgetDescription(){ 43returndescription; 44} 45publicvoidsetDescription(Stringdescription){ 46this.description=description; 47} 48publicIntegergetRoleId(){ 49returnroleId; 50} 51publicvoidsetRoleId(IntegerroleId){ 52this.roleId=roleId; 53} 54 55 56 57}用户角色表:
1packagecom.ssh.entity; 2 3importjavax.persistence.CascadeType; 4importjavax.persistence.Entity; 5importjavax.persistence.GeneratedValue; 6importjavax.persistence.GenerationType; 7importjavax.persistence.Id; 8importjavax.persistence.JoinColumn; 9importjavax.persistence.ManyToOne; 10importjavax.persistence.Table; 11 12@Entity 13@Table(name="t_user_role") 14publicclassUserRole{ 15@Id 16@GeneratedValue(strategy=GenerationType.AUTO) 17Integerid; 18 19@ManyToOne(cascade=CascadeType.ALL) 20@JoinColumn(name="userId",unique=true) 21Useruser; 22@ManyToOne 23@JoinColumn(name="roleId",unique=true) 24Rolerole; 25publicIntegergetId(){ 26returnid; 27} 28publicvoidsetId(Integerid){ 29this.id=id; 30} 31publicUsergetUser(){ 32returnuser; 33} 34publicvoidsetUser(Useruser){ 35this.user=user; 36} 37publicRolegetRole(){ 38returnrole; 39} 40publicvoidsetRole(Rolerole){ 41this.role=role; 42} 43 44}BaseDao
1packagecom.ssh.dao; 2 3importjava.util.List; 4 5publicinterfaceBaseDao{ 6 7/*** 8*添加 9*/ 10publicvoidaddObject(Objectobject); 11 12/*** 13*查询满足条件returnlist 14*/ 15publicListfindAllByHQL(Stringhql); 16 17/*** 18*查询满足条件的数据 19* 20*@paramhql 21*@paramargs 22*@return 23*/ 24publicListfindAllByHQL(Stringhql,Object[]args); 25 26/*** 27*查询满足条件的对象 28*/ 29publicObjectfindObjectByHQL(Stringhql); 30 31publicObjectfindObjectByHQL(Stringhql,Object[]args); 32 33/*** 34*查询满足条件的对象 35*/ 36publicObjectfindObjectBySQL(Stringsql); 37 38/*** 39*分页查询returnlist 40*/ 41publicListfindPage(Stringhql,intpage,intsize); 42 43/*** 44*分页查询带占位符参数 45* 46*@paramhql 47*@parampage 48*@paramsize 49*@paramargs 50*@return 51*/ 52publicListfindPage(Stringhql,intpage,intsize,Object[]args); 53 54/*** 55*删除对象 56*/ 57publicvoiddelObject(Objectobject); 58 59/*** 60*更新对象 61*/ 62publicvoidupdateObject(Objectobject); 63 64/*** 65*批量更新对象returnint 66*/ 67publicvoidupdateObjectByHQL(Stringhql); 68 69publicvoidupdateObjectByHQL(Stringhql,Object[]params); 70 71/*** 72*通过sql查询所有 73* 74*@paramsql 75*@return 76*/ 77publicListfindAllBySql(Stringsql); 78 79}BaseDaoImpl
1packagecom.ssh.dao; 2 3importjava.util.List; 4 5importorg.hibernate.Query; 6importorg.hibernate.SessionFactory; 7importorg.springframework.transaction.annotation.Transactional; 8 9@Transactional 10publicclassBaseDaoImplimplementsBaseDao{ 11//@Autowired 12publicSessionFactorysessionFactory; 13 14publicSessionFactorygetSessionFactory(){ 15returnsessionFactory; 16} 17 18publicvoidsetSessionFactory(SessionFactorysessionFactory){ 19this.sessionFactory=sessionFactory; 20} 21 22 23publicvoidaddObject(Objectobject){ 24sessionFactory.getCurrentSession().save(object); 25} 26 27publicListfindAllByHQL(Stringhql){ 28Queryquery=sessionFactory.getCurrentSession().createQuery(hql); 29returnquery.list(); 30} 31 32publicListfindAllByHQL(Stringhql,Object[]args){ 33Queryquery=sessionFactory.getCurrentSession().createQuery(hql); 34for(inti=0;i<args.length;i++){ 35System.out.println(args[i]); 36query.setParameter(i,args[i]); 37} 38returnquery.list(); 39} 40 41 42publicObjectfindObjectByHQL(Stringhql){ 43Queryquery=sessionFactory.getCurrentSession().createQuery(hql); 44Listlist=query.list(); 45if(list.size()>0){ 46returnlist.get(0); 47} 48returnnull; 49} 50 51publicObjectfindObjectByHQL(Stringhql,Object[]args){ 52Queryquery=sessionFactory.getCurrentSession().createQuery(hql); 53System.out.println(args[0]); 54for(inti=0;i<args.length;i++){ 55System.out.println(args[i]); 56query.setParameter(i,args[i]); 57} 58Listlist=query.list(); 59if(list.size()>0){ 60returnlist.get(0); 61} 62returnnull; 63} 64 65publicListfindPage(finalStringhql,finalintpage,finalintsize,finalObject[]args){ 66Queryquery=sessionFactory.getCurrentSession().createQuery(hql); 67for(inti=0;i<args.length;i++){ 68query.setParameter(i,args[i]); 69} 70query.setMaxResults(size); 71query.setFirstResult(page); 72List<Object>list=query.list(); 73returnlist; 74} 75 76publicListfindPage(finalStringhql,finalintpage,finalintsize){ 77Queryquery=sessionFactory.getCurrentSession().createQuery(hql); 78query.setMaxResults(size); 79query.setFirstResult(page); 80List<Object>list=query.list(); 81returnlist; 82} 83 84publicvoiddelObject(Objectobject){ 85sessionFactory.getCurrentSession().delete(object); 86} 87 88 89publicvoidupdateObject(Objectobject){ 90sessionFactory.getCurrentSession().update(object); 91} 92 93 94publicvoidupdateObjectByHQL(Stringhql){ 95sessionFactory.getCurrentSession().createQuery(hql).executeUpdate(); 96} 97 98 99publicObjectfindObjectBySQL(Stringsql){ 100Queryquery=sessionFactory.getCurrentSession().createSQLQuery(sql); 101 102Listlist=query.list(); 103if(list.size()>0){ 104returnlist.get(0); 105} 106returnnull; 107} 108 109publicListfindAllBySql(Stringsql){ 110Queryquery=sessionFactory.getCurrentSession().createSQLQuery(sql); 111returnquery.list(); 112} 113 114publicvoidupdateObjectByHQL(Stringhql,Object[]params){ 115Queryquery=sessionFactory.getCurrentSession().createQuery(hql); 116for(inti=0;i<params.length;i++){ 117query.setParameter(i,params[i]); 118} 119query.executeUpdate(); 120} 121 122}上述类继承了Shiro的AuthorizingRealm类实现了AuthorizationInfo和AuthenticationInfo两个方法,用于获取用户权限和认证用户登录信息
spring-shiro.xml
1<?xmlversion="1.0"encoding="UTF-8"?> 2<beansxmlns="http://www.springframework.org/schema/beans" 3xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx" 4xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context" 5xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsd 6http://www.springframework.org/schema/context 7http://www.springframework.org/schema/context/spring-context-3.2.xsd 8http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.2.xsd 9http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"> 10 11<!--shiro-all.jar 12filterChainDefinitions:apache 13shiro通过filterChainDefinitions参数来分配链接的过滤, 14资源过滤有常用的以下几个参数: 15authc表示需要认证的链接 16perms[/url]表示该链接需要拥有对应的资源/权限才能访问 17roles[admin]表示需要对应的角色才能访问 18perms[admin:url]表示需要对应角色的资源才能访问 19 20--> 21<beanid="shiroFilter"class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 22<propertyname="securityManager"ref="securityManager"/> 23<propertyname="loginUrl"value="/toLogin"/> 24<propertyname="successUrl"value="/home"/> 25<propertyname="unauthorizedUrl"value="/403.do"/> 26 27<propertyname="filterChainDefinitions"> 28<value> 29/toLogin=authc<!--authc表示需要认证才能访问的页面--> 30/home=authc,perms[/home]<!--perms表示需要该权限才能访问的页面--> 31</value> 32</property> 33</bean> 34 35<beanid="myShiroRealm"class="com.ssh.shiro.MyShiroRealm"> 36<!--businessManager用来实现用户名密码的查询--> 37<propertyname="accountService"ref="accountService"/> 38</bean> 39<!--shiro-all.jar--> 40<beanid="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 41<propertyname="realm"ref="myShiroRealm"></property> 42</bean> 43 44<beanid="accountService"class="com.ssh.service.AccountService"></bean> 45 46<!--<beanid="shiroCacheManager"class="org.apache.shiro.cache.ehcache.EhCacheManager"> 47<propertyname="cacheManager"ref="cacheManager"/></bean>--> 48</beans>loginUrl用于配置登陆页
successUrl用于配置登录成功后返回的页面,不过该参数只会在当登录页面中并没有任何返回页面时才会生效,否则会跳转到登录Controller中的指定页面。
unauthorizedUrl用于配置没有权限访问页面时跳转的页面
filterChainDefinitions:apacheshiro通过filterChainDefinitions参数来分配链接的过滤,资源过滤有常用的以下几个参数:
1、authc表示需要认证的链接
2、perms[/url]表示该链接需要拥有对应的资源/权限才能访问
3、roles[admin]表示需要对应的角色才能访问
4、perms[admin:url]表示需要对应角色的资源才能访问
spring-common.xml
1<?xmlversion="1.0"encoding="UTF-8"?> 2<beansxmlns="http://www.springframework.org/schema/beans" 3xmlns:aop="http://www.springframework.org/schema/aop" 4xmlns:cache="http://www.springframework.org/schema/cache" 5xmlns:context="http://www.springframework.org/schema/context" 6xmlns:jdbc="http://www.springframework.org/schema/jdbc" 7xmlns:jee="http://www.springframework.org/schema/jee" 8xmlns:jms="http://www.springframework.org/schema/jms" 9xmlns:lang="http://www.springframework.org/schema/lang" 10xmlns:mvc="http://www.springframework.org/schema/mvc" 11xmlns:oxm="http://www.springframework.org/schema/oxm" 12xmlns:task="http://www.springframework.org/schema/task" 13xmlns:tx="http://www.springframework.org/schema/tx" 14xmlns:util="http://www.springframework.org/schema/util" 15xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 16xsi:schemaLocation="http://www.springframework.org/schema/beans 17http://www.springframework.org/schema/beans/spring-beans.xsd 18http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.2.xsd 19http://www.springframework.org/schema/cachehttp://www.springframework.org/schema/cache/spring-cache-3.2.xsd 20http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsd 21http://www.springframework.org/schema/jdbchttp://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd 22http://www.springframework.org/schema/jeehttp://www.springframework.org/schema/jee/spring-jee-3.2.xsd 23http://www.springframework.org/schema/jmshttp://www.springframework.org/schema/jms/spring-jms-3.2.xsd 24http://www.springframework.org/schema/langhttp://www.springframework.org/schema/lang/spring-lang-3.2.xsd 25http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 26http://www.springframework.org/schema/oxmhttp://www.springframework.org/schema/oxm/spring-oxm-3.2.xsd 27http://www.springframework.org/schema/taskhttp://www.springframework.org/schema/task/spring-task-3.2.xsd 28http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-3.2.xsd 29http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-3.2.xsd"> 30 31<!--扫描映射--> 32<context:component-scanbase-package="com.ssh"></context:component-scan> 33 34<!--引入property配置文件--> 35<context:property-placeholderlocation="classpath:prop/jdbc.properties"></context:property-placeholder> 36<!--配置数据源--> 37<beanclass="org.springframework.jdbc.datasource.DriverManagerDataSource"id="dataSource"> 38<propertyname="driverClassName"value="${jdbc.mysql.driverClassName}"></property> 39<propertyname="url"value="${jdbc.mysql.url}"></property> 40<propertyname="username"value="${jdbc.mysql.username}"></property> 41<propertyname="password"value="${jdbc.mysql.password}"></property> 42<!--初始化连接大小 43<propertyname="initialSize"value="${jdbc.initialSize}"></property>--> 44<!--连接池最大数量 45<propertyname="maxActive"value="${jdbc.maxActive}"></property>--> 46<!--连接池最大空闲--> 47<!--<propertyname="maxIdle"value="${maxIdle}"></property>--> 48<!--连接池最小空闲 49<propertyname="minIdle"value="${jdbc.minIdle}"></property>--> 50<!--获取连接最大等待时间 51<propertyname="maxWait"value="${jdbc.maxWait}"></property>--> 52</bean> 53 54<!--配置SessionFactory--> 55<beanclass="org.springframework.orm.hibernate4.LocalSessionFactoryBean"id="sessionFactory"> 56<propertyname="dataSource"ref="dataSource"></property> 57<propertyname="hibernateProperties"> 58<props> 59<propkey="hibernate.dialect">${jdbc.mysql.dialect}</prop> 60<propkey="hibernate.hbm2ddl.auto">update</prop> 61<!--是否显示sql语句我在这里是显示的--> 62<propkey="hibernate.show_sql">true</prop> 63<!--格式化显示sql语句--> 64<propkey="hibernate.format_sql">true</prop> 65</props> 66</property> 67<!--自动扫描制定位置下的实体进行映射--> 68<propertyname="packagesToScan"value="com.ssh.entity"></property> 69</bean> 70 71<!--配置一个事务管理器--> 72<beanclass="org.springframework.orm.hibernate4.HibernateTransactionManager"id="transactionManager"> 73<propertyname="sessionFactory"ref="sessionFactory"> 74</property></bean> 75 76<!--应该是开启事物--> 77<tx:annotation-driventransaction-manager="transactionManager"></tx:annotation-driven> 78 79<!--baseDao--> 80<beanid="dao"class="com.ssh.dao.BaseDaoImpl"> 81<propertyname="sessionFactory"ref="sessionFactory"></property> 82</bean> 83</beans>spring-mvc.xml
1<?xmlversion="1.0"encoding="UTF-8"?> 2<beansxmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans 3http://www.springframework.org/schema/beans/spring-beans.xsd 4http://www.springframework.org/schema/context 5http://www.springframework.org/schema/context/spring-context-3.2.xsd 6http://www.springframework.org/schema/mvc 7http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> 8 9<!--注解扫描包--> 10<context:component-scanbase-package="com.ssh"></context:component-scan> 11 12<!--开启注解--> 13<mvc:annotation-driven></mvc:annotation-driven> 14 15<!--定义视图解析器--> 16<beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver"id="viewResolver"> 17<propertyname="prefix"value="/WEB-INF/page/"></property> 18<propertyname="suffix"value=".jsp"></property> 19</bean> 20<importresource="spring-common.xml"/> 21<importresource="spring-shiro.xml"/> 22</beans>在数据库中添加一条用户、角色、以及权限数据,并且在关联表中添加一条关联数据:
在浏览器中访问:home页面就会跳转到登录页面:
最后输入账号密码就会跳转到登录成功页面。
本文内容总结:第一部分什么是ApacheShiro,1、什么是apacheshiro:,2、ApacheShiro的三大核心组件:,3、Authentication和Authorization,4、其他组件:,5、Shiro完整架构图:,第二部分ApacheShiro整合Spring的Web程序构建,1、准备工具:,2、创建数据库:,3、编写操作用户业务的Service:,4、编写shiro组件自定义Realm:,5、编写LoginController:,6、编写信息认证成功后的跳转页面:,7、Shiro的配置文件.xml,8、登陆页login.jsp,9、运行程序,
原文链接:https://www.cnblogs.com/sharpest/p/5865732.html