在整合Shiro的时候,我们先要确定一下我们的步骤:

1.加入Shiro的依赖包,实现自己的Realm类(通过继承AuthorizingRealm类);

2.实现Shiro的配置类

3.实现前端的登录界面以及Controller类

第一步:

在pom.xml中加入依赖包

<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.0</version></dependency>

实现Realm类

package ariky.shiro.realm;import java.util.HashSet;
import java.util.Set;import javax.servlet.http.HttpServletRequest;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.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
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 org.apache.shiro.web.subject.WebSubject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/**
* @ClassName:
* @Description: Realm的配置
* @author fuweilian
* @date 2018-5-12 上午11:36:41*/
public class MyShiroRealm extends AuthorizingRealm {//slf4j记录日志,可以不使用private Logger logger = LoggerFactory.getLogger(MyShiroRealm.class);/*** 设置授权信息*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {logger.info("开始授权(doGetAuthorizationInfo)");SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();HttpServletRequest request = (HttpServletRequest) ((WebSubject) SecurityUtils.getSubject()).getServletRequest();//这个可以用来获取在登录的时候提交的其他额外的参数信息String username = (String) principals.getPrimaryPrincipal();//这里是写的demo,后面在实际项目中药通过这个登录的账号去获取用户的角色和权限,这里直接是写死的//受理权限//角色Set<String> roles = new HashSet<String>();roles.add("role1");authorizationInfo.setRoles(roles);//权限Set<String> permissions = new HashSet<String>();permissions.add("user:list");//permissions.add("user:add");authorizationInfo.setStringPermissions(permissions);return authorizationInfo;}/*** 设置认证信息*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {logger.info("开始认证(doGetAuthenticationInfo)");//UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;HttpServletRequest request = (HttpServletRequest) ((WebSubject) SecurityUtils.getSubject()).getServletRequest();UsernamePasswordToken token = new UsernamePasswordToken (request.getParameter("userName"),request.getParameter("password"));//获取用户输入的账号String userName = (String)token.getPrincipal();//通过userName去数据库中匹配用户信息,通过查询用户的情况做下面的处理//这里暂时就直接写死,根据登录用户账号的情况做处理logger.info("账号:"+userName);if("passwordError".equals(userName)){//密码错误throw new IncorrectCredentialsException(); }else if("lockAccount".equals(userName)){// 用户锁定throw new LockedAccountException(); }else{SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userName, //用户名"123456", //密码,写死ByteSource.Util.bytes(userName+"salt"),//salt=username+saltgetName()  //realm name);return authenticationInfo;}}}

第二步 实现Shiro的配置类:

package ariky.shiro.configuration;import java.util.LinkedHashMap;
import java.util.Map;import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import ariky.shiro.realm.MyShiroRealm;/**
* @ClassName: ShiroConfiguration
* @Description: shiro的配置类
* @author fuweilian
* @date 2018-5-12 上午11:05:09*/
@Configuration
public class ShiroConfiguration {private static Logger logger = LoggerFactory.getLogger(ShiroConfiguration.class);@Bean(name = "shiroFilter")public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){logger.info("进入shiroFilter......");ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);//设置不需要拦截的路径Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String, String>();//按顺序依次判断filterChainDefinitionMap.put("/static/**", "anon");//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了filterChainDefinitionMap.put("/logout", "logout");//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->/************************************初始化所有的权限信息开始******************************************///这里,如果以后再项目中使用的话,直接从数据库中查询filterChainDefinitionMap.put("/user/list", "authc,perms[user:list]");//filterChainDefinitionMap.put("/user/add", "authc,perms[user:add]");/***************************************初始化所有的权限信息开始结束*********************************************/filterChainDefinitionMap.put("/**", "authc");// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面shiroFilterFactoryBean.setLoginUrl("/login");// 登录成功后要跳转的链接shiroFilterFactoryBean.setSuccessUrl("/index");//未授权界面shiroFilterFactoryBean.setUnauthorizedUrl("/error/403");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}@Beanpublic MyShiroRealm myShiroRealm(){MyShiroRealm myShiroRealm = new MyShiroRealm();//后面这里可以设置缓存的机制return myShiroRealm;} @Beanpublic SecurityManager securityManager(){DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();securityManager.setRealm(myShiroRealm());return securityManager;}@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);return authorizationAttributeSourceAdvisor;}}

第三步:实现Controoler类,这里写俩个类,一个是登录信息的LoginController处理类,一个是测试权限用的UserController

1.LoginController.java

package ariky.controller;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;/**
* @ClassName: LoginController
* @Description: 登录控制的controller
* @author fuweilian
* @date 2018-5-12 下午01:15:46*/
@RequestMapping
@Controller
public class LoginController {private Logger logger = LoggerFactory.getLogger(LoginController.class);@RequestMapping(value="/login",method=RequestMethod.GET)public String getLogin(){logger.info("进入login页面");return "login";}@RequestMapping(value="/login",method=RequestMethod.POST)public String doLogin(HttpServletRequest req,Map<String, Object> model){logger.info("进入登录处理");String exceptionClassName = (String) req.getAttribute("shiroLoginFailure");logger.info("exceptionClassName:"+exceptionClassName);String error = null;if (UnknownAccountException.class.getName().equals(exceptionClassName)) {error = "用户名/密码错误";} else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {error = "用户名/密码错误";}else if(LockedAccountException.class.getName().equals(exceptionClassName)){ error = "用户已锁定或已删除";}else if (exceptionClassName != null) {error = "其他错误:" + exceptionClassName;}if(SecurityUtils.getSubject().isAuthenticated()){//没有错误,但是已经登录了,就直接跳转到welcom页面model.put("name", req.getParameter("userName"));return "index";}else{//有错误的model.put("error", error);return "login";}}@RequestMapping("/index")public String index(){return "index";}
}

2.UserController.java

package ariky.controller;import java.util.ArrayList;
import java.util.List;import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;/**
* @ClassName: UserController
* @Description: 用户处理Controller
* @author fuweilian
* @date 2018-5-12 下午03:11:06*/
@Controller
@RequestMapping("/user")
public class UserController {Logger logger = LoggerFactory.getLogger(UserController.class);@RequiresPermissions("user:list")//这个是配置是否有该权限的,如果是按上面的写法,这个是有权限的@RequestMapping(value="/list",method=RequestMethod.GET)public String getList(){logger.info("进入用户列表");return "user/list";}@RequiresPermissions(value={"user:add"})//这个是没有权限的@RequestMapping(value="/add",method=RequestMethod.GET)public String getAdd(){logger.info("进入新增用户界面");return "user/add";}}

前端界面:有5个界面 (login.jsp,index.jsp,list.jsp,add.jsp,403.jsp)

目录结构为:

1.login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Login</title>
</head><body><h1>登录页面----${error}</h1><form:form action="${pageContext.request.contextPath }/login"method="post">用户名:<input type="text" name="userName"><br />密码:<input type="passwordParam" name="password"/><input type="submit" value="提交"/></form:form>
</body>
</html>

2.index.jsp

<%@ page language="java" pageEncoding="UTF-8"%><%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>第一个例子</title>
<script src="${pageContext.request.contextPath }/webjars/jquery/2.1.4/jquery.js"></script>
<script src="${pageContext.request.contextPath }/webjarslocator/jquery/jquery.js"></script>
</head><body><h1>${name}:你好,欢迎访问该网页</h1><shiro:hasPermission name="user:list"><!-- 这个a标签是可以看见的 --><a href="${pageContext.request.contextPath }/user/list" target="_blank">跳转到用户列表(有权限)</a></shiro:hasPermission><br/><shiro:hasPermission name="user:add"><!-- 这个a标签是看不见的 --><a href="${pageContext.request.contextPath }/user/add" target="_blank">跳转到新增用户列表(无权限)</a></shiro:hasPermission>
</body>
</html>

3.list.jsp和add.jsp以及403.jsp都差不多一样,这里就写一个,这里只是demo所用,在实际项目中,要以实际项目为准

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>userList</title>
</head><body><h1>用户列表信息</h1>
</body>
</html>

如果启动成功,进入login登录界面就可以测试一下shiro的权限认证了。上面的代码都是写死的,如果想要实现动态的权限管理和用户的权限管理的话,还要做一些其他处理,用户的动态权限这个只要在自己的ShiroRealm类里面授权的时候做一下查询数据库,动态的授权和角色就行。关于动态的权限管理的话,下面的方式可以实现,在修改完权限数据后,更新一下shiro里面的配置就行,具体看下面的代码,这里是demo,不是实际项目,在实际项目中最好不要把逻辑写在Controller里面

package ariky.shiro.controller;import java.util.LinkedHashMap;
import java.util.Map;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;/**
* @ClassName: PermssionController
* @Description: 权限操作的controller
* @author fuweilian
* @date 2018-5-12 下午04:59:15*/
@Controller
@RequestMapping("permssion")
public class PermssionController {@AutowiredShiroFilterFactoryBean shiroFilterFactoryBean;/*** @Title: updatePermssion * @author: fuweilian* @Description: 这里暂时直接写在controller里面,,不按规则写了,,到时候在项目中使用的时候,才写* @return  参数说明 * @return Object    返回类型 * @throws*/@RequestMapping("/updatePermssion")@ResponseBodypublic Object updatePermssion(){synchronized (shiroFilterFactoryBean){AbstractShiroFilter shiroFilter = null;try {shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();// 清空老的权限控制manager.getFilterChains().clear();shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();//后面这个可以直接从数据库里面获取Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String, String>();//按顺序依次判断filterChainDefinitionMap.put("/static/**", "anon");//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了filterChainDefinitionMap.put("/logout", "logout");//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->/************************************初始化所有的权限信息开始******************************************///这里,如果以后再项目中使用的话,直接从数据库中查询filterChainDefinitionMap.put("/user/list", "authc,perms[user:list]");filterChainDefinitionMap.put("/user/add", "authc,perms[user:add]");/***************************************初始化所有的权限信息开始结束*********************************************/filterChainDefinitionMap.put("/**", "authc");//shiroFilterFactoryBean.setLoginUrl("/login");// 登录成功后要跳转的链接shiroFilterFactoryBean.setSuccessUrl("/index");//未授权界面shiroFilterFactoryBean.setUnauthorizedUrl("/error/403");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);// 重新构建生成Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();for (Map.Entry<String, String> entry : chains.entrySet()) {String url = entry.getKey();String chainDefinition = entry.getValue().trim().replace(" ", "");manager.createChain(url, chainDefinition);}return "更新权限成功";  } catch (Exception e) {throw new RuntimeException("更新shiro权限出现错误!");}}}}
/*
Navicat MySQL Data Transfer
Source Server         : arikyDB
Source Server Version : 50721
Source Host           : 47.106.95.168:3306
Source Database       : ariky
Target Server Type    : MYSQL
Target Server Version : 50721
File Encoding         : 65001
Date: 2018-05-14 16:05:51
*/SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for common_permssion
-- ----------------------------
DROP TABLE IF EXISTS `common_permssion`;
CREATE TABLE `common_permssion` (`ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`NAME` varchar(255) DEFAULT NULL COMMENT '权限名称',`TYPE` varchar(255) DEFAULT NULL COMMENT '类型按钮(button)或者菜单(menu) ',`PARENT_ID` int(11) DEFAULT NULL COMMENT '上级ID',`PARENT_IDS` varchar(255) DEFAULT NULL COMMENT '上级PIDs',`URL` varchar(255) DEFAULT NULL COMMENT '访问路径',`ICONCLS` varchar(255) DEFAULT NULL COMMENT '图标(可以不要)',`PERMISSION` varchar(255) DEFAULT NULL COMMENT '权限(如user:list)',`ORDER_NUM` int(11) DEFAULT NULL COMMENT '排序',`REMARK` varchar(255) DEFAULT NULL COMMENT '备注',PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8 COMMENT='该表用来存储资源权限信息';-- ----------------------------
-- Table structure for common_role
-- ----------------------------
DROP TABLE IF EXISTS `common_role`;
CREATE TABLE `common_role` (`ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`LABEL_ID` varchar(255) DEFAULT NULL COMMENT '标签Id',`NAME` varchar(255) DEFAULT NULL COMMENT '角色名称',`ROLE` varchar(255) DEFAULT NULL,`DESCRIPTION` varchar(255) DEFAULT NULL,`IS_SHOW` int(11) DEFAULT '1' COMMENT '判断该角色是否在使用(1:使用,2:禁用)',`IS_HANDLER` int(2) DEFAULT NULL COMMENT '判断是什么角色(1:后台角色,2:商家管理员角色,3:商家添加用户角色,4:游客角色)',PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COMMENT='角色表';-- ----------------------------
-- Table structure for common_role_permssion
-- ----------------------------
DROP TABLE IF EXISTS `common_role_permssion`;
CREATE TABLE `common_role_permssion` (`ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键Id',`ROLE_ID` int(11) DEFAULT NULL COMMENT '角色Id',`RESOURCE_ID` int(11) DEFAULT NULL COMMENT '资源(权限)Id',PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=493 DEFAULT CHARSET=utf8 COMMENT='角色资源权限表中间表';

SpringBoot中关于Shiro权限管理的整合使用相关推荐

  1. SpringBoot系列 - 集成Shiro权限管理

    Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,相比Spring Security而言相当简单, 可能没有Spring Security做的功能强大, ...

  2. Spring +mybatisplus+shiro权限管理集成整合

    一.Apache Shiro是一个功能强大.灵活的,开源的安全框架.它可以干净利落地处理身份验证.授权.企业会话管理和加密. Shiro能做什么呢? 验证用户身份 用户访问权限控制,比如:1.判断用户 ...

  3. Springboot之Shiro权限管理

    文章目录 Springboot之Shiro权限管理 介绍 1.shiro有三个核心api(接口) 2.如何使用: 第一步导入shiro与springboot整合依赖 第二步配置shiro类 第三步自定 ...

  4. (39.3) Spring Boot Shiro权限管理【从零开始学Spring Boot】

    在学习此小节之前您可能还需要学习: (39.1) Spring Boot Shiro权限管理[从零开始学Spring Boot] http://412887952-qq-com.iteye.com/b ...

  5. Spring Boot Shiro 权限管理

    Spring Boot Shiro 权限管理 标签: springshiro 2016-01-14 23:44 94587人阅读 评论(60) 收藏 举报 本来是打算接着写关于数据库方面,集成MyBa ...

  6. 39 Spring Boot Shiro权限管理【从零开始学Spring Boot】

    [视频 & 交流平台] à SpringBoot视频 http://study.163.com/course/introduction.htm?courseId=1004329008& ...

  7. SSM集成shiro权限管理

    这几天在学习了shiro权限管理框架,在刚开始的时候学的时候因为这个配置问题困扰了我很长时间,所以在这篇文章我整合了自己用SSM搭建shiro权限框架的过程. 1.配置 1.1jar包 在项目配置开始 ...

  8. Shiro权限管理详解

    1权限管理1.1什么是权限管理 基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权 ...

  9. SpringMVC+Shiro权限管理

    SpringMVC+Shiro权限管理 什么是权限呢?举个简单的例子: 我有一个论坛,注册的用户分为normal用户,manager用户. 对论坛的帖子的操作有这些: 添加,删除,更新,查看,回复 我 ...

最新文章

  1. python中字符串运算符及用法_python将字符串转换为运算符
  2. java的修饰符_java默认的修饰符是什么
  3. ASP運行Excel.Application出錯
  4. java图片特效轮播代码_JQuery实现图片轮播效果
  5. 腾讯加持,雷军力荐,这款游戏手机要火?
  6. java 字节流写入_Java之基于字节流文件的写入和读取
  7. Spring 3.x 企业应用开发实战(含CD光盘1张)
  8. redis源码剖析(5):基础数据结构inset
  9. 通过设置proxyTable实现调用接口跨域
  10. Java 添加、验证PDF 数字签名
  11. (day 49 - 另起数组牺牲空间换取时间 ) 剑指 Offer 66. 构建乘积数组
  12. 【转】每天一个linux命令(11):nl命令
  13. 注册测绘师考试有用吗
  14. 基于Babylon.js编写宇宙飞船模拟程序1——程序基础结构、物理引擎使用、三维罗盘
  15. 卡内基梅隆大学计算机系难考,考出托福成绩 成功申请卡内基梅隆大学计算机科学专业...
  16. Vue引入百度地图增加导航功能
  17. 紫砂壶的起源 计算机操作题,紫砂壶的起源与历史发展你知道吗?
  18. 国内支持Amazon Alexa的智能家居
  19. 5G通信技术书籍分享(持续更新)
  20. UEStudio注册码机 文本编辑器软件v2020.10.21

热门文章

  1. Flume 1.7 源码分析(三)程序入口
  2. 容器源码分析之PriorityQueue(十)
  3. AlphaGo:人工智能与深度学习
  4. HipHop算法:利用微博互动关系挖掘社交圈
  5. 电话聊天狂人 (25 分)【简便解法】
  6. C语言满分代码:L1-056 猜数字 (20分)
  7. 堆排序算法c语言筛选法,【排序】排序算法之选择排序
  8. vue 左右滑动菜单_Vue实现左右菜单联动实现代码
  9. python2的xrange比range的优点_python相对于range应该更倾向于实用xrange吗
  10. cfile 修改某些位_王者荣耀:打野刀效果再次修改,自定义房间配置试运行!