SSM集成Shiro安全框架(一)
2018-10-23 18:33
330 查看
一、目录结构
二、基础配置文件
1.pom.xml
[code] <!-- 引入shiro框架 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.3</version> </dependency> <dependency> <artifactId>ehcache-core</artifactId> <groupId>net.sf.ehcache</groupId> <version>2.5.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-quartz</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency> <!-- Shiro 集成验证码 --> <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </dependency>
2.web.xml
[code] <!-- 配置 Shiro 的 Filter --> <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> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>ERROR</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping>
3.shiro.sql
[code]/* Navicat MySQL Data Transfer Source Server : localhost_3306 Source Server Version : 50537 Source Host : localhost:3306 Source Database : shiro Target Server Type : MYSQL Target Server Version : 50537 File Encoding : 65001 Date: 2018-09-03 10:12:43 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `permission` -- ---------------------------- DROP TABLE IF EXISTS `permission`; CREATE TABLE `permission` ( `id` bigint(8) NOT NULL AUTO_INCREMENT, `name` varchar(16) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of permission -- ---------------------------- INSERT INTO `permission` VALUES ('1', 'addProduct'); INSERT INTO `permission` VALUES ('2', 'deleteProduct'); INSERT INTO `permission` VALUES ('3', 'editeProduct'); INSERT INTO `permission` VALUES ('4', 'updateProduct'); INSERT INTO `permission` VALUES ('5', 'listProduct'); INSERT INTO `permission` VALUES ('6', 'addOrder'); INSERT INTO `permission` VALUES ('7', 'deleteOrder'); INSERT INTO `permission` VALUES ('8', 'editeOrder'); INSERT INTO `permission` VALUES ('9', 'updateOrder'); INSERT INTO `permission` VALUES ('10', 'listOrder'); -- ---------------------------- -- Table structure for `role` -- ---------------------------- DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `id` bigint(8) NOT NULL AUTO_INCREMENT, `name` varchar(16) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of role -- ---------------------------- INSERT INTO `role` VALUES ('1', 'admin'); INSERT INTO `role` VALUES ('2', 'productManager'); INSERT INTO `role` VALUES ('3', 'orderManager'); -- ---------------------------- -- Table structure for `role_permission` -- ---------------------------- DROP TABLE IF EXISTS `role_permission`; CREATE TABLE `role_permission` ( `rid` bigint(20) NOT NULL DEFAULT '0', `pid` bigint(20) NOT NULL DEFAULT '0', PRIMARY KEY (`rid`,`pid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of role_permission -- ---------------------------- INSERT INTO `role_permission` VALUES ('1', '1'); INSERT INTO `role_permission` VALUES ('1', '2'); INSERT INTO `role_permission` VALUES ('1', '3'); INSERT INTO `role_permission` VALUES ('1', '4'); INSERT INTO `role_permission` VALUES ('1', '5'); INSERT INTO `role_permission` VALUES ('1', '6'); INSERT INTO `role_permission` VALUES ('1', '7'); INSERT INTO `role_permission` VALUES ('1', '8'); INSERT INTO `role_permission` VALUES ('1', '9'); INSERT INTO `role_permission` VALUES ('1', '10'); INSERT INTO `role_permission` VALUES ('2', '1'); INSERT INTO `role_permission` VALUES ('2', '2'); INSERT INTO `role_permission` VALUES ('2', '3'); INSERT INTO `role_permission` VALUES ('2', '4'); INSERT INTO `role_permission` VALUES ('2', '5'); INSERT INTO `role_permission` VALUES ('3', '6'); INSERT INTO `role_permission` VALUES ('3', '7'); INSERT INTO `role_permission` VALUES ('3', '8'); INSERT INTO `role_permission` VALUES ('3', '9'); INSERT INTO `role_permission` VALUES ('3', '10'); -- ---------------------------- -- Table structure for `user` -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint(8) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, `password` varchar(32) DEFAULT NULL, `salt` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('1', 'admin', '68609b8b64988c0f4def093eaa025e05', 'abcd'); INSERT INTO `user` VALUES ('2', 'li4', 'abcde', 'abcd'); -- ---------------------------- -- Table structure for `user_role` -- ---------------------------- DROP TABLE IF EXISTS `user_role`; CREATE TABLE `user_role` ( `uid` bigint(20) NOT NULL DEFAULT '0', `rid` bigint(20) NOT NULL DEFAULT '0', PRIMARY KEY (`uid`,`rid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user_role -- ---------------------------- INSERT INTO `user_role` VALUES ('1', '1'); INSERT INTO `user_role` VALUES ('1', '2'); INSERT INTO `user_role` VALUES ('2', '2');
三、权限控制demo
1.Spring配置文件(applicationContext.xml)中导入shiro配置文件:
[code] <!-- 引入shiro的配置文件 --> <import resource="classpath:applicationContext-shiro.xml" /> <!-- 7 -->
2.shiro配置文件applicationContext-shiro.xml
[code]<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" 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/tx http://www.springframework.org/schema/tx/spring-tx-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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 调用我们配置的权限管理器 --> <property name="securityManager" ref="securityManager" /> <!-- 配置我们的登录请求地址 --> <property name="loginUrl" value="/login.jsp" /> <!-- 配置我们在登录页登录成功后的跳转地址,如果你访问的是非/login地址,则跳到您访问的地址 --> <property name="successUrl" value="/index.jsp" /> <!-- 如果您请求的资源不再您的权限范围,则跳转到/403请求地址 --> <property name="unauthorizedUrl" value="/unauthorized.jsp" /> <property name="filters"> <util:map> <entry key="logout" value-ref="logoutFilter" /> </util:map> </property> <!-- 权限配置 --> <property name="filterChainDefinitions"> <value> <!-- anon表示此地址不需要任何权限即可访问 --> /login=anon /kaptcha=anon /kaptcha/get=anon /icon/**=anon /js/**=anon /css/**=anon <!-- -->/index.jsp = roles[admin] <!--/index.jsp = roles["admin","productManager"] 要同时具有admin,productManager两个角色权限 --> <!--/index.jsp = roleOrFilter["admin","productManager"] 只需具有其中一个权限就可以,但需要自定义filter --> /logout=logout <!-- 所有的请求(除去配置的静态资源请求或请求地址为anon的请求)都要通过登录验证,如果未登录则跳到/login --> /** = authc </value> </property> </bean> <!-- 退出登陆配置 --> <bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter"> <!-- 重定向退出登陆的地址 --> <property name="redirectUrl" value="logout.jsp" /> </bean> <!-- 会话ID生成器 --> <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" /> <!-- 会话Cookie模板 关闭浏览器立即失效 --> <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg value="sid" /> <property name="httpOnly" value="true" /> <property name="maxAge" value="-1" /> </bean> <!-- 会话DAO --> <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"> <property name="sessionIdGenerator" ref="sessionIdGenerator" /> </bean> <!-- 会话验证调度器,每30分钟执行一次验证 ,设定会话超时及保存 --> <bean name="sessionValidationScheduler" class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler"> <property name="interval" value="1800000" /> <property name="sessionManager" ref="sessionManager" /> </bean> <!-- 会话管理器 --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <!-- 全局会话超时时间(单位毫秒),默认30分钟 --> <property name="globalSessionTimeout" value="1800000" /> <property name="deleteInvalidSessions" value="true" /> <property name="sessionValidationSchedulerEnabled" value="true" /> <property name="sessionValidationScheduler" ref="sessionValidationScheduler" /> <property name="sessionDAO" ref="sessionDAO" /> <property name="sessionIdCookieEnabled" value="true" /> <property name="sessionIdCookie" ref="sessionIdCookie" /> </bean> <!-- 安全管理器 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="userRealm" /> <!-- 1 --> <!-- 使用下面配置的缓存管理器 --> <property name="cacheManager" ref="cacheManager" /> <property name="sessionManager" ref="sessionManager" /> </bean> <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) --> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager" /> <property name="arguments" ref="securityManager" /> </bean> <!-- 注册自定义的Realm,并把密码匹配器注入,使用注解的方式自动注解会无法正确匹配密码 --> <bean id="userRealm" class="com.yan.shiro.common.UserRealm"><!-- 2 --> <!-- 将凭证匹配器设置到realm中,realm按照凭证匹配器的要求进行散列 --> <property name="credentialsMatcher" ref="credentialsMatcher" /> </bean> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="MD5"></property> <!-- 加密算法的名称 --> <property name="hashIterations" value="1024"></property> <!-- 配置加密的次数 --> </bean> <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> </bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.apache.shiro.authz.UnauthorizedException">/403</prop> </props> </property> </bean> </beans>
3.定义shiro拦截器(UserRealm.java)
[code]package com.yan.shiro.common; import java.util.Set; 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.crypto.hash.SimpleHash; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import com.yan.shiro.model.User; import com.yan.shiro.service.UserService; public class UserRealm extends AuthorizingRealm { @Autowired private UserService userService; /** * 授权 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("UserRealm的doGetAuthorizationInfo方法开始执行"); //获取当前登陆的用户名 String username=(String)principals.getPrimaryPrincipal(); System.out.println("username:"+username); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); //从数据库中查找该用户名拥有的角色 Set<String> roleList = userService.selectRoleByUserName(username); // 添加角色 authorizationInfo.addRoles(roleList); // 添加权限 // authorizationInfo.setStringPermissions(userService.findPermissions(username)); return authorizationInfo; } /** * 登陆验证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("UserRealm的doGetAuthenticationInfo方法开始执行"); //获取当前登陆的用户名 String userName = (String) token.getPrincipal(); //从数据库中获取user User user = userService.selectByUserName(userName); // 为密码加盐 ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());// 这里的参数要给个唯一的; // 校验 SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getName(), user.getPassword(),credentialsSalt, getName()); return authenticationInfo; } public static void main(String[] args) { SimpleHash MD5 = new SimpleHash("MD5", "123456", ByteSource.Util.bytes("小明"), 1024); System.out.println(MD5); } }
4.UserController.java
[code] @RequestMapping(value = "/login", method = RequestMethod.POST) public String login(HttpServletRequest request) { System.out.println("UserController的login方法开始执行"); String username = request.getParameter("username"); String password = request.getParameter("password"); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username,password); try { //执行认证操作. subject.login(token); } catch (Exception e) { e.printStackTrace(); return "error"; } return "success"; }
四、JSP标签
1.导入标签库
[code]<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
2.guest标签
[code]<shiro:guest> 欢迎游客访问,<a href="${pageContext.request.contextPath}/login.jsp">登录</a> </shiro:guest>
3.user 标签
[code]<shiro:user> 欢迎 用户访问,<a href="${pageContext.request.contextPath}/login.jsp">登录</a> </shiro:user>
4.principal 标签
[code]<!-- 显示用户身份信息,默认调用 Subject.getPrincipal() 获取--> <shiro:principal type="java.lang.String"/><!-- 相当于 Subject.getPrincipals().oneByType(String.class) --> <shiro:principal type="java.lang.String"/> <!-- 相当于 Subject.getPrincipals().oneByType(String.class) -->
5.lacksRole 标签
[code]<shiro:lacksRole name="abc"> 用户[<shiro:principal/>]没有角色abc<br/> <!-- 如果当前 Subject abc角色将显示 body 体内容。 --> </shiro:lacksRole>
6.hasPermission 标签
[code]<shiro:hasPermission name="user:create"> 用户[<shiro:principal/>]拥有权限user:create<br/> <!-- 如果当前 Subject 有create权限将显示 body 体内容。 --> </shiro:hasPermission>
7.lacksPermission 标签
[code]<shiro:lacksPermission name="org:create"> 用户[<shiro:principal/>]没有权限org:create<br/> <!-- 如果当前 Subject 没有create权限将显示 body 体内容。 --> </shiro:lacksPermission>
阅读更多
相关文章推荐
- SSM集成安全框架shiro
- SSM集成Shiro安全框架(二)
- SSM集成Shiro安全框架(三)
- AdminEAP框架-集成Shiro安全认证
- ssm搭建shiro安全框架
- SSM框架下的shiro集成
- java安全框架-Shiro学习笔记(五)-Shiro集成Web
- 基于Spirng的Shiro安全框架与CAS SSO的集成
- SSM集成Shiro:实现登录认证
- 安全框架Shiro和Spring Security比较
- 基于权限安全框架Shiro的登录验证功能实现
- Shiro安全框架相关配置
- 安全框架-Shiro
- 安全框架Shiro和Spring Security比较
- 开源安全框架Apache Shiro
- ssm+shiro基础框架搭建(一)
- Shiro (Java安全框架)
- SpringBoot集成Spring Security安全框架
- 【SSM框架 SSM项目源码 SSM源码 下载】java框架整合Springmvc+mybatis+shiro+bootstrap
- 快速搭建springboot框架以及整合ssm+shiro+安装Rabbitmq和Erlang、Mysql下载与配置