Spring MVC整合Shiro权限控制的方法

Apache Shiro 是一个功能强大且灵活的开放源代码安全框架,可以细粒度地处理认证 (Authentication),授权 (Authorization),会话 (Session) 管理和加密 (cryptography) 等企业级应用中常见的安全控制流程。 Apache Shiro 的首要目标是易于使用和理解。 有时候安全性的流程控制会非常复杂,对开发人员来说是件很头疼的事情,但并不一定如此。 框架就应该尽可能地掩盖复杂性,并公开一个简洁而直观的 API,从而简化开发人员的工作,确保其应用程序安全性。这次我们聊一聊如何在 Spring Web 应用中使用 Shiro 实现权限控制。

功能

Apache Shiro 是一个具有许多功能的综合型应用程序安全框架。 下图为 Shiro 中的最主要的几个功能:

Shiro 的主要目标是“应用安全的四大基石” - 认证,授权,会话管理和加密:

  1. 身份验证:也就是通常所说的 “登录”,为了证明用户的行为所有者。
  2. 授权:访问控制的过程,即确定什么用户可以访问哪些内容。
  3. 会话管理:即使在非 Web 应用程序中,也可以管理用户特定的会话,这也是 Shiro 的一大亮点。
  4. 加密技术:使用加密算法保证数据的安全,非常易于使用。

架构

从整体概念上理解,Shiro 的体系架构有三个主要的概念:Subject (主体,也就是用户),Security Manager (安全管理器)和 Realms (领域)。 下图描述了这些组件之间的关系:

这几大组件可以这样理解:

  1. Subject (主体):主体是当前正在操作的用户的特定数据集合。主体可以是一个人,也可以代表第三方服务,守护进程,定时任务或类似的东西,也就是几乎所有与该应用进行交互的事物。
  2. Security Manager (安全管理器):它是 Shiro 的体系结构的核心,扮演了类似于一把 “伞” 的角色,它主要负责协调内部的各个组件,形成一张安全网。
  3. Realms (领域):Shiro 与应用程序安全数据之间的 “桥梁”。当需要实际与用户帐户等安全相关数据进行交互以执行认证和授权时,Shiro 将从 Realms 中获取这些数据。

数据准备

在 Web 应用中,对安全的控制主要有角色、资源、权限(什么角色能访问什么资源)几个概念,一个用户可以有多个角色,一个角色也可以访问多个资源,也就是角色可以对应多个权限。落实到数据库设计上,我们至少需要建 5 张表:用户表、角色表、资源表、角色-资源表、用户-角色表,这 5 张表的结构如下:

用户表:

id username password
1 张三 123456
2 李四 666666
3 王五 000000

角色表:

id rolename
1 管理员
2 经理
3 员工

资源表:

id resname
1 /user/add
2 /user/delete
3 /compony/info

角色-资源表:

id roleid resid
1 1 1
2 1 2
3 2 3

用户-角色表:

id userid roleid
1 1 1
2 1 2
3 1 3

对应的 POJO 类如下:

/**
 * 用户
 */
public class User {
 private Integer id;
 private String username;
 private String password;
 //getter & setter...
}
/**
 * 角色
 */
public class Role {
 private String id;
 private String rolename;
}
/**
 * 资源
 */
public class Resource {
 private String id;
 private String resname;
}
/**
 * 角色-资源
 */
public class RoleRes {
 private String id;
 private String roleid;
 private String resid;
}
/**
 * 用户-角色
 */
public class UserRole {
 private String id;
 private String userid;
 private String roleid;
}

Spring 与 Shiro 整合的详细步骤,请参阅我的博客 《 Spring 应用中整合 Apache Shiro》 。 这里补充一下:需要提前引入 Shiro 的依赖,打开mvnrepository.com,搜索 Shiro,我们需要前三个依赖,也就是 Shiro-Core、Shiro-Web 以及 Shiro-Spring,以 Maven 项目为例,在 pom.xml 中的 <dependencies> 节点下添加如下依赖:

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

application-context.xml 中需要这样配置 shiroFilter bean:

<!-- 配置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"/>
 <!-- 登录成功后的页面 -->
 <property name="successUrl" value="/index"/>
 <!-- 非法访问跳转的页面 -->
 <property name="unauthorizedUrl" value="/403"/>
 <!-- 权限配置 -->
 <property name="filterChainDefinitions">
 <value>
  <!-- 无需认证即可访问的静态资源,还可以添加其他 url -->
  /static/** = anon
  <!-- 除了上述忽略的资源,其他所有资源都需要认证后才能访问 -->
  /** = authc
 </value>
 </property>
</bean>

接下来就需要定义 Realm 了,自定义的 Realm 集成自 AuthorizingRealm 类:

public class MyRealm extends AuthorizingRealm {
 @Autowired
 private UserService userService;
 /**
 * 验证权限
 */
 @Override
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
 String loginName = SecurityUtils.getSubject().getPrincipal().toString();
 if (loginName != null) {
 String userId = SecurityUtils.getSubject().getSession().getAttribute("userSessionId").toString();
 // 权限信息对象,用来存放查出的用户的所有的角色及权限
 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
 // 用户的角色集合
 ShiroUser shiroUser = (ShiroUser) principalCollection.getPrimaryPrincipal();
  info.setRoles(shiroUser.getRoles());
  info.addStringPermissions(shiroUser.getUrlSet());
 return info;
 }
 return null;
 }
 /**
 * 认证回调函数,登录时调用
 */
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
 String username = (String) token.getPrincipal();
 User user = new User();
 sysuser.setUsername(username);
 try {
 List<SysUser> users = userService.findByNames(user);
  List<String> roleList= userService.selectRoleNameListByUserId(users.get(0).getId());
 if (users.size() != 0) {
 String pwd = users.get(0).getPassword();
 // 当验证都通过后,把用户信息放在 session 里
 Session session = SecurityUtils.getSubject().getSession();
 session.setAttribute("userSession", users.get(0));
 session.setAttribute("userSessionId", users.get(0).getId());
 session.setAttribute("userRoles", org.apache.commons.lang.StringUtils.join(roleList,","));
  return new SimpleAuthenticationInfo(username,users.get(0).getPassword());
 } else {
  // 没找到该用户
 throw new UnknownAccountException();
 }
 } catch (Exception e) {
 System.out.println(e.getMessage());
 }
 return null;
 }
 /**
 * 更新用户授权信息缓存.
 */
 public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
 super.clearCachedAuthorizationInfo(principals);
 }
 /**
 * 更新用户信息缓存.
 */
 public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
 super.clearCachedAuthenticationInfo(principals);
 }
 /**
 * 清除用户授权信息缓存.
 */
 public void clearAllCachedAuthorizationInfo() {
 getAuthorizationCache().clear();
 }
 /**
 * 清除用户信息缓存.
 */
 public void clearAllCachedAuthenticationInfo() {
 getAuthenticationCache().clear();
 }
 /**
 * 清空所有缓存
 */
 public void clearCache(PrincipalCollection principals) {
 super.clearCache(principals);
 }
 /**
 * 清空所有认证缓存
 */
 public void clearAllCache() {
 clearAllCachedAuthenticationInfo();
 clearAllCachedAuthorizationInfo();
 }
}

最后定义一个用户登录的控制器,接受用户的登录请求:

@Controller
public class UserController {
 /**
 * 用户登录
 */
 @PostMapping("/login")
 public String login(@Valid User user,BindingResult bindingResult,RedirectAttributes redirectAttributes){
 try {
  if(bindingResult.hasErrors()){
  return "login";
  }
  //使用权限工具进行认证,登录成功后跳到 shiroFilter bean 中定义的 successUrl
  SecurityUtils.getSubject().login(new UsernamePasswordToken(user.getUsername(), user.getPassword()));
  return "redirect:index";
 } catch (AuthenticationException e) {
  redirectAttributes.addFlashAttribute("message","用户名或密码错误");
  return "redirect:login";
 }
 }
 /**
 * 注销登录
 */
 @GetMapping("/logout")
 public String logout(RedirectAttributes redirectAttributes ){
 SecurityUtils.getSubject().logout();
 return "redirect:login";
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • spring boot整合Shiro实现单点登录的示例代码

    Shiro是什么 Shiro是一个Java平台的开源权限框架,用于认证和访问授权.具体来说,满足对如下元素的支持: 用户,角色,权限(仅仅是操作权限,数据权限必须与业务需求紧密结合),资源(url). 用户分配角色,角色定义权限. 访问授权时支持角色或者权限,并且支持多级的权限定义. Q:对组的支持? A:shiro默认不支持对组设置权限. Q:是否可以满足对组进行角色分配的需求? A:扩展Realm,可以支持对组进行分配角色,其实就是给该组下的所有用户分配权限. Q:对数据权限的支持? 在业务

  • spring整合shiro框架的实现步骤记录

    shiro Shiro是Apache下的一个开源项目,我们称之为Apache Shiro.它是一个很易用与Java项目的的安全框架,提供了认证.授权.加密.会话管理,与spring Security 一样都是做一个权限的安全框架,但是与Spring Security 相比,在于 Shiro 使用了比较简单易懂易于使用的授权方式.shiro属于轻量级框架,相对于security简单的多,也没有security那么复杂.更多详细的介绍可以从它的官网上(http://shiro.apache.org/

  • SpringBoot整合Shiro实现登录认证的方法

    安全无处不在,趁着放假读了一下 Shiro 文档,并记录一下 Shiro 整合 Spring Boot 在数据库中根据角色控制访问权限 简介 Apache Shiro是一个功能强大.灵活的,开源的安全框架.它可以干净利落地处理身份验证.授权.企业会话管理和加密. 上图是 Shiro 的基本架构 Authentication(认证) 有时被称为"登录",用来证明用户是用户他们自己本人 Authorization(授权) 访问控制的过程,即确定"谁"访问"什么

  • spring boot整合redis实现shiro的分布式session共享的方法

    我们知道,shiro是通过SessionManager来管理Session的,而对于Session的操作则是通过SessionDao来实现的,默认的情况下,shiro实现了两种SessionDao,分别为CachingSessionDAO和MemorySessionDAO,当我们使用EhCache缓存时,则是使用的CachingSessionDAO,不适用缓存的情况下,就会选择基于内存的SessionDao.所以,如果我们想实现基于Redis的分布式Session共享,重点在于重写Session

  • Apache shiro的简单介绍与使用教程(与spring整合使用)

    apache shiro框架简介 Apache Shiro是一个强大而灵活的开源安全框架,它能够干净利落地处理身份认证,授权,企业会话管理和加密.现在,使用Apache Shiro的人越来越多,因为它相当简单,相比比Spring Security,Shiro可能没有Spring Security那么多强大的功能,但是在实际工作时可能并不需要那么复杂的东西,所以使用简单的Shiro就足够了. 以下是你可以用 Apache Shiro所做的事情: Shiro的4大核心部分--身份验证,授权,会话管理

  • SpringBoot整合Shiro的代码详解

    shiro是一个权限框架,具体的使用可以查看其官网 http://shiro.apache.org/  它提供了很方便的权限认证和登录的功能. 而springboot作为一个开源框架,必然提供了和shiro整合的功能!接下来就用springboot结合springmvc,mybatis,整合shiro完成对于用户登录的判定和权限的验证. 1.准备数据库表结构 这里主要涉及到五张表:用户表,角色表(用户所拥有的角色),权限表(角色所涉及到的权限),用户-角色表(用户和角色是多对多的),角色-权限表

  • Spring 整合Shiro 并扩展使用EL表达式的实例详解

    Shiro是一个轻量级的权限控制框架,应用非常广泛.本文的重点是介绍Spring整合Shiro,并通过扩展使用Spring的EL表达式,使@RequiresRoles等支持动态的参数.对Shiro的介绍则不在本文的讨论范围之内,读者如果有对shiro不是很了解的,可以通过其官方网站了解相应的信息.infoq上也有一篇文章对shiro介绍比较全面的,也是官方推荐的,其地址是https://www.infoq.com/articles/apache-shiro. Shiro整合Spring 首先需要

  • 详解spring整合shiro权限管理与数据库设计

    之前的文章中我们完成了基础框架的搭建,现在基本上所有的后台系统都逃不过权限管理这一块,这算是一个刚需了.现在我们来集成shiro来达到颗粒化权限管理,也就是从连接菜单到页面功能按钮,都进行权限都验证,从前端按钮的显示隐藏,到后台具体功能方法的权限验证. 首先要先设计好我们的数据库,先来看一张比较粗糙的数据库设计图: 具体的数据库设计代码 /* Navicat MySQL Data Transfer Source Server : 本机 Source Server Version : 50537

  • Spring MVC整合Shiro权限控制的方法

    Apache Shiro 是一个功能强大且灵活的开放源代码安全框架,可以细粒度地处理认证 (Authentication),授权 (Authorization),会话 (Session) 管理和加密 (cryptography) 等企业级应用中常见的安全控制流程. Apache Shiro 的首要目标是易于使用和理解. 有时候安全性的流程控制会非常复杂,对开发人员来说是件很头疼的事情,但并不一定如此. 框架就应该尽可能地掩盖复杂性,并公开一个简洁而直观的 API,从而简化开发人员的工作,确保其应

  • Spring Boot2开发之Spring Boot整合Shiro两种详细方法

    在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. Spring Security 和 Shiro 的比较: Spring Security 是一个重量级的安全管理框架:Shiro 则是一个轻量级的安全管理框架 Spring Security 概念复杂,配置繁琐:Shiro 概念简单.配置简单 Spring Security 功能强大:Shiro 功能简单 等等 虽然 Shiro 功能简单,但是也

  • Spring MVC整合 freemarker及使用方法

    1.什么是Spring MVC? Spring MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将Web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,SpringMVC框架的目的就是帮助我们简化开发. Spring MVC 实现了即用的 MVC 的核心概念.它为控制器和处理程序提供了大量与此模式相关的功能.并且当向 MVC 添加反转控制(Inversion of Control,IoC)时,它使应用程序高度解耦,提供

  • springboot2.x整合shiro权限框架的使用

    序 在实际项目中,经常需要用到角色权限区分,以此来为不同的角色赋予不同的权利,分配不同的任务.比如,普通用户只能浏览:会员可以浏览和评论:超级会员可以浏览.评论和看视频课等:实际应用场景很多.毫不夸张的说,几乎每个完整的项目都会设计到权限管理. 在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是由于 Spring Security 过于庞大和复杂,只要能满足业务需要,大多数公司还是会选择 Apache Shiro 来使用. 一般来说,Spri

  • Java框架搭建之Maven、Mybatis、Spring MVC整合搭建(图文)

    本文主要介绍了Java框架搭建之Maven.Mybatis.Spring MVC整合搭建(图文),分享给大家,具体如下: SSM(Spring+SpringMVC+Mybatis),目前较为主流的企业级架构方案.标准的MVC设计模式,将整个系统划分为显示层.Controller层.Service层.Dao层四层,使用SpringMVC负责请求的转发和视图管理,Spring实现业务对象管理, MyBatis作为数据对象持久化引擎. 框架详情 Spring 是一个轻量级的Java开发框架,它是为了解

  • spring boot整合shiro安全框架过程解析

    这篇文章主要介绍了spring boot整合shiro安全框架过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 题记:在学习了springboot和thymeleaf之后,想完成一个项目练练手,于是使用springboot+mybatis和thymeleaf完成一个博客系统,在完成的过程中出现的一些问题,将这些问题记录下来,作为自己的学习心得.在这先感谢群主TyCoding的Tumo项目,虽然本人实在太菜了,好些地方看不懂,但还是使我受益

  • Spring boot整合shiro+jwt实现前后端分离

    本文实例为大家分享了Spring boot整合shiro+jwt实现前后端分离的具体代码,供大家参考,具体内容如下 这里内容很少很多都为贴的代码,具体内容我经过了看源码和帖子加了注释.帖子就没用太多的内容 先下载shiro和jwt的jar包 <!-- shiro包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId

  • Spring Security 中细化权限粒度的方法

    有小伙伴表示微人事(https://github.com/lenve/vhr)的权限粒度不够细.不过松哥想说的是,技术都是相通的,明白了 vhr 中权限管理的原理,在此基础上就可以去细化权限管理粒度,细化过程和还是用的 vhr 中用的技术,只不过设计层面重新规划而已. 当然今天我想说的并不是这个话题,主要是想和大家聊一聊 Spring Security 中权限管理粒度细化的问题.因为这个问题会涉及到不同的权限管理模型,今天和小伙伴们聊一聊- 1.权限管理模型 要想将细化权限粒度,我们不可避免会涉

  • Spring mvc整合mybatis(crud+分页插件)操作mysql

    一.web.xml配置 我们都知道java ee的项目启动的第一件事就是读取web.xml,spring mvc 的web.xml我在上一篇文章中也做了详细讲解,不懂的可以回头看看,讲解的这个项目源码我也会放到github上,也可以去那里看看,这里就不做介绍了. web.xml 配置 <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/c

  • SpringBoot整合Security权限控制登录首页

    目录 在 pom 文件中增加thymeleaf页面支持 application.yml 配置文件 login 页面 controller目录下跳转配置 UserController 在 pom 文件中增加thymeleaf页面支持 <!-- 引入页面模板 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thym

随机推荐