2019独角兽企业重金招聘Python工程师标准>>>

Spring Boot + Shiro 集成

Shiro 是一个流行的 Java 安全框架。

其实 Spring 有一个 Spring Security 的安全框架,我试用了一下,太复杂了。同样的安全需求,用 Shiro 要简单、快捷得多,也利于理解。

本手册的源码托管在 GitHub 上:

YorkeCao/shiro-spring-boot-sample

下面主要介绍在 Spring Boot 项目中引入 Shiro,对应用进行安全管控。

集成

可以利用 Shiro 启动器来完成与 Spring Boot 的集成。

这里为了简单,尽量少做配置。实际上 Shiro 有很多自定义选项。详细介绍请移步官网。

  1. 引入 Shiro 启动器

    Shiro 官方提供了 Spring Boot 启动器:shiro-spring-boot-starter,在 pom.xml 文件中引入:

    <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring-boot-starter -->
    <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId><version>1.4.0</version>
    </dependency>
    

  2. 配置 Shiro

    这里我们提供一个最简单的 Java Class 配置。

    里面用到了一个自定义的 Realm:CustomRealm。

    package io.yorkecao.sample.config;import io.yorkecao.sample.shiro.CustomRealm;
    import org.apache.shiro.spring.LifecycleBeanPostProcessor;
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;/*** @author Yorke*/
    @Configuration
    public class ShiroConfig {@Bean(name = "customRealm")public CustomRealm customRealm() {return new CustomRealm();}@Bean(name = "securityManager")public DefaultWebSecurityManager defaultWebSecurityManager(CustomRealm customRealm) {DefaultWebSecurityManager  securityManager = new DefaultWebSecurityManager ();securityManager.setRealm(customRealm);return securityManager;}@Bean(name = "lifecycleBeanPostProcessor")public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {return new LifecycleBeanPostProcessor();}@Bean(name = "shiroFilter")public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();shiroFilterFactoryBean.setSecurityManager(securityManager);return shiroFilterFactoryBean;}
    }
    

  3. 实现自定义 Realm

    Realm 是控制认证和授权的核心部分,也是开发人员必须自己实现的部分。

    实现自定义 Realm 最快捷的方式是继承 AuthorizingRealm 类。

    package io.yorkecao.sample.shiro;import io.yorkecao.sample.dao.ShiroSampleDao;
    import org.apache.shiro.authc.*;
    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.springframework.beans.factory.annotation.Autowired;import java.util.Set;/*** @author Yorke*/
    public class CustomRealm extends AuthorizingRealm {@Autowiredprivate ShiroSampleDao shiroSampleDao;/*** 认证*/@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;String username = token.getUsername();String password = this.shiroSampleDao.getPasswordByUsername(username);return new SimpleAuthenticationInfo(username, password, getName());}/*** 授权*/@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {String username = (String) super.getAvailablePrincipal(principalCollection);SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();Set<String> roles = shiroSampleDao.getRolesByUsername(username);authorizationInfo.setRoles(roles);roles.forEach(role -> {Set<String> permissions = this.shiroSampleDao.getPermissionsByRole(role);authorizationInfo.addStringPermissions(permissions);});return authorizationInfo;}
    }
    

    这里用到了一个 DAO:shiroSampleDao。应该要通过它来从我们的数据库中获取用户、角色等信息。但是为了方便,我只是模拟了一下。

    package io.yorkecao.sample.dao;import org.springframework.stereotype.Repository;import java.util.*;/*** @author Yorke*/
    @Repository
    public class ShiroSampleDao {public Set<String> getRolesByUsername(String username) {Set<String> roles = new HashSet<>();switch (username) {case "zhangsan":roles.add("admin");break;case "lisi":roles.add("guest");break;}return roles;}public Set<String> getPermissionsByRole(String role) {Set<String> permissions = new HashSet<>();switch (role) {case "admin":permissions.add("read");permissions.add("write");break;case "guest":permissions.add("read");break;}return permissions;}public String getPasswordByUsername(String username) {switch (username) {case "zhangsan":return "zhangsan";case "lisi":return "lisi";}return null;}
    }
    

  4. 实现 login、logout 接口

    在 Shiro 框架中实现登录、登出很容易。

    这里我也提供了一个 read 和 write 的接口,这两个接口在 Service 实现。

    package io.yorkecao.sample.web;import io.yorkecao.sample.service.ShiroSampleService;
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.subject.Subject;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;/*** @author Yorke*/
    @RestController
    public class ShiroSampleController {@Autowiredprivate ShiroSampleService shiroSampleService;@GetMapping("/login")public void login(String username, String password) {UsernamePasswordToken token = new UsernamePasswordToken(username, password);token.setRememberMe(true);Subject currentUser = SecurityUtils.getSubject();currentUser.login(token);}@GetMapping("/logout")public void logout() {Subject currentUser = SecurityUtils.getSubject();currentUser.logout();}@GetMapping("/read")public String read() {return this.shiroSampleService.read();}@GetMapping("/write")public String write() {return this.shiroSampleService.write();}
    }
    

  5. 通过注解设置访问资源所需权限

    可以通过 @RequiresPermissions 等注解设置访问资源所需的权限。

    package io.yorkecao.sample.service;import org.apache.shiro.authz.annotation.RequiresPermissions;
    import org.springframework.stereotype.Service;/*** @author Yorke*/
    @Service
    public class ShiroSampleService {@RequiresPermissions("read")public String read() {return "reading...";}@RequiresPermissions("write")public String write() {return "writting...";}
    }
    

测试

  • 在登录之前,访问 /read/write 接口都无效
  • 用 lisi 登录(GET http://localhost:8080/login?username=lisi&password=lisi)后,可以访问 /read,不能访问 /write
  • 用 zhangsan 登录(GET http://localhost:8080/login?username=zhangsan&password=zhangsan)后,/read/write 都可以访问
  • 登出后,访问 /read/write 接口都无效

转载于:https://my.oschina.net/YorkeCao/blog/1058017

Spring Boot + Shiro 集成相关推荐

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

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

  2. Spring Boot Shiro 权限管理

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

  3. Spring boot Shiro 用户认证

    在Spring Boot中集成Shiro进行用户的认证过程主要可以归纳为以下三点: 1.定义一个ShiroConfig,然后配置SecurityManager Bean,SecurityManager ...

  4. Spring Boot 工程集成全局唯一ID生成器 Vesta

    2019独角兽企业重金招聘Python工程师标准>>> 本文内容脑图如下: 文章共 760字,阅读大约需要 2分钟 ! 概 述 在前一篇文章 <Spring Boot工程集成全 ...

  5. 在spring boot中集成Swagger

    Swagger 在spring boot中集成Swagger 新建一个swagger项目 maven依赖 <!-- https://mvnrepository.com/artifact/io.s ...

  6. Spring Boot 快速集成第三方登录功能

    Spring Boot 快速集成第三方登录功能 前言 此 demo 主要演示 Spring Boot 项目如何使用 史上最全的第三方登录工具 - JustAuth 实现第三方登录,包括 QQ 登录.G ...

  7. spring boot shiro redis整合基于角色和权限的安全管理-Java编程

    一.概述 本博客主要讲解spring boot整合Apache的shiro框架,实现基于角色的安全访问控制或者基于权限的访问安全控制,其中还使用到分布式缓存redis进行用户认证信息的缓存,减少数据库 ...

  8. Spring/Spring boot正确集成Quartz及解决@Autowired失效问题

    Spring/Spring boot正确集成Quartz及解决@Autowired失效问题 参考文章: (1)Spring/Spring boot正确集成Quartz及解决@Autowired失效问题 ...

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

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

最新文章

  1. SpringCloud 教程 | 第二篇: 服务消费者(rest+ribbon)
  2. PHP学习笔记-字符串操作2
  3. TCP之三次握手四次挥手 1
  4. 【arduino】不做不死系列,用arduino玩CyberPi童芯派之helloworld点灯
  5. C++轻量级微服务_微服务技术栈:API网关中心,落地实现方案
  6. addeventlistener不支持ajax_好程序员web前端学习路线分享了解AJAX是什么
  7. dns代表计算机哪个术语,windows dns 术语解释
  8. mysql workbench首页_MySQL Workbench是干什么的?
  9. java设计模式--01类图UML图箭头含义
  10. deepin,真好用-09-deepin真垃圾
  11. 棋牌游戏开发制做花费,您知多少呢?
  12. 阿里云服务器价格是多少,阿里云服务器价格查询的三种方式
  13. oracle start with connect by order siblings by用法
  14. 关于iPhone尺寸与分辨率
  15. mac 删除Microsoft office word中的空白页的方法
  16. SpringBoot 快速集成 JWT 实现用户登录认证
  17. 黑苹果详细安装教程-基于OpenCore官网指导-UPUPMO(macOS Monterey)
  18. 华为南研所校招软件技术岗几点建议
  19. 蓝桥 第八大奇迹 (线段树)
  20. php tip,jQuery tip提示插件详解

热门文章

  1. 性能相差极大的SQL语句
  2. jquery mobile资源
  3. HDU 4879 ZCC loves march (并查集,set,map)
  4. 一起用ipython
  5. ubuntu无法获得锁 /var/lib/dpkg -open 问题
  6. BZOJ1078 [SCOI2008]斜堆 堆
  7. 【线性代数】向量空间
  8. Python之路,Day9 - 线程、进程、协程和IO多路复用
  9. SQL JOIN\SQL INNER JOIN 关键字\SQL LEFT JOIN 关键字\SQL RIGHT JOIN 关键字\SQL FULL JOIN 关键字...
  10. 阿里云mariadb无法启动问题