0、写在前面的话

好久没写博客了,诶,好多时候偷懒直接就抓网上的资料丢笔记里了,也就没有自己提炼,偷懒偷懒。然后最近参加了一个网络课程,要交作业的那种,为了能方便看下其他同学的作业,就写了个爬虫把作业爬下来,进而想到如果以后还有类似这种情况,我需要一个非常轻量化的架子,但是权限依然是必须要用到的,否则写个接口人人都可以调用那还得了,但是我仅仅需要一个人或者一两个人的权限配置就可以了,所以像之前我写过一个基于RBAC的架子甚至都还是有点嫌重(而且那个架子还没有前端页面,哈,真是懒),所以想到了用shiro.ini。

Shiro在很多quick start的demo中都用到了shiro.ini配置文件,用来配置账户密码、角色、权限,它也写好了现成的方法可以读取文件直接给你配置好SecurityManager,所以省去了自己在代码里定义Realm、配置过滤器啥的,但是实际上大家在做Web时基本都不用这玩意儿,因为自定义其实也不是很费时,我也就是蛋疼吧,既然都鼓捣了,那就还是鼓捣到有个雏形。

1、踩坑记录

Shiro好久没碰了,又重新回顾了下大概几个概念:
  • SecurityManager是核心,所有和安全有关的操作都要和它交互,而且管理者所有Subject
  • Realm用来验证用户,可以理解为DataSource安全数据源
  • 权限拦截是通过过滤器,配置好urls和shiro默认过滤器的映射关系,shiro将会对requestUrl进行过滤链的匹配,并选择过滤器进行处理

[users]
zhang=123,admin
wang=123,admin,vip [roles]
admin=user:delete [urls]
/static/**=anon
/login=anon
/authc/admin/user/delete=perms["user:delete"]
/authc/admin/user/create=perms["user:create"]
/authc/admin/**=roles[admin]
/authc/home=roles[admin,vip]
/authc/**=authc
x
17
 
1
[users]
2
zhang=123,admin
3
wang=123,admin,vip
4

5
[roles]
6
admin=user:delete
7

8

9
[urls]
10
/static/**=anon
11
/login=anon
12
/authc/admin/user/delete=perms["user:delete"]
13
/authc/admin/user/create=perms["user:create"]
14
/authc/admin/**=roles[admin]
15
/authc/home=roles[admin,vip]
16
/authc/**=authc
shiro.ini中的 [main] 用不上了,因为这部分的配置和SpringBoot结合就在类中进行配置,这里就不需要了,只需要 [users]、[roles]、[urls],其中[users] 和 [roles] 用来创建 Realm,[urls] 用来配置过滤器

踩坑:
  • urls过滤匹配中,是按顺序执行匹配到的第一个过滤器,所以要注意顺序,如上图如果把 /authc/** 放在开头,后面的基本就匹配不到了
  • urls中对于诸如perms或roles的描述,是“且”不是“或”
    • 比如 roles[admin,vip] 表示同时拥有admin和vip角色的账户,而不是拥有admin或vip角色的账户
  • * 匹配零个或多个字符    ** 匹配零个或多个路径

@Configuration
public class ShiroConfig { @Bean
public DefaultWebSecurityManager securityManager() {
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance(); DefaultSecurityManager defaultSecurityManager = (DefaultSecurityManager) securityManager;
DefaultWebSecurityManager webSecurityManager = new DefaultWebSecurityManager();
webSecurityManager.setRealms(defaultSecurityManager.getRealms()); //important SecurityUtils.setSecurityManager(securityManager);
return webSecurityManager;
} @Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager); Ini ini = new Ini();
ini.loadFromPath("classpath:shiro.ini");
Map<String, String> map = new LinkedHashMap<>(); ini.getSection("urls").entrySet().forEach(url -> {
map.put(url.getKey(), url.getValue());
});
//过滤链
shiroFilterFactoryBean.setFilterChainDefinitionMap(map); shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
return shiroFilterFactoryBean;
} }
x
 
1
@Configuration
2
public class ShiroConfig {
3

4
    @Bean
5
    public DefaultWebSecurityManager securityManager() {
6
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
7
        SecurityManager securityManager = factory.getInstance();
8

9
        DefaultSecurityManager defaultSecurityManager = (DefaultSecurityManager) securityManager;
10
        DefaultWebSecurityManager webSecurityManager = new DefaultWebSecurityManager();
11
        webSecurityManager.setRealms(defaultSecurityManager.getRealms()); //important
12

13
        SecurityUtils.setSecurityManager(securityManager);
14
        return webSecurityManager;
15
    }
16

17
    @Bean
18
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
19
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
20
        shiroFilterFactoryBean.setSecurityManager(securityManager); 
21

22
        Ini ini = new Ini();
23
        ini.loadFromPath("classpath:shiro.ini");
24
        Map<String, String> map = new LinkedHashMap<>();
25

26
        ini.getSection("urls").entrySet().forEach(url -> {
27
            map.put(url.getKey(), url.getValue());
28
        });
29
        //过滤链
30
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
31

32
        shiroFilterFactoryBean.setLoginUrl("/login");
33
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
34
        return shiroFilterFactoryBean;
35
    }
36

37
}

踩坑
  • SecurityManager是一定要有的,但是Shiro中读取shiro返回的是 DefaultSecurityManager,因为是Web应用我们需要的是 DefaultWebSecurityManager,所以把 DefaultSecurityManager的Realms 提出来给 DefaultWebSecurityManager
  • 过滤链还是得注入在Bean中的 FilterChainDefinitionMap 属性才是,所以对于shiro.ini的配置,使用 Ini 类的 loadFromPath 来读取,再放置到map中

...
<packaging>war</packaging>
... ...
<!-- jsp支持 start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency> <dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- jsp支持 end -->
...
1
12
 
1
...
2
<packaging>war</packaging>
3
...
4

5
...
6
<!-- jsp支持 start -->
7
<dependency>
8
    <groupId>org.springframework.boot</groupId>
9
    <artifactId>spring-boot-starter-tomcat</artifactId>
10
    <scope>provided</scope>
11
</dependency>
12

13
<dependency>
14
    <groupId>org.apache.tomcat.embed</groupId>
15
    <artifactId>tomcat-embed-jasper</artifactId>
16
</dependency>
17
<!-- jsp支持 end -->
18
...
#application.properties
spring.mvc.view.prefix=/WEB-INF/pages/
spring.mvc.view.suffix=.jsp
1
 
1
#application.properties
2
spring.mvc.view.prefix=/WEB-INF/pages/
3
spring.mvc.view.suffix=.jsp

SpringBoot 对 JSP 的支持并不友好,所以需要一些额外的配置,参考资料《Spring Boot 添加 JSP 支持

SpringBoot + Shiro + shiro.ini 的踩坑记录的更多相关文章

  1. SpringBoot+SpringSecurity+Thymeleaf认证失败返回错误信息踩坑记录

    Spring boot +Spring Security + Thymeleaf认证失败返回错误信息踩坑记录 步入8102年,现在企业开发追求快速,Springboot以多种优秀特性引领潮流,在众多使 ...

  2. unionId突然不能获取的踩坑记录

    昨天(2016-2-2日),突然发现系统的一个微信接口使用不了了.后来经查发现,是在网页授权获取用户基本信息的时候,unionid获取失败导致的. 在网页授权获取用户基本信息的介绍中(http://m ...

  3. CentOS7.4安装MySQL踩坑记录

    CentOS7.4安装MySQL踩坑记录 time: 2018.3.19 CentOS7.4安装MySQL时网上的文档虽然多但是不靠谱的也多, 可能因为版本与时间的问题, 所以记录下自己踩坑的过程, ...

  4. ubuntu 下安装docker 踩坑记录

    ubuntu 下安装docker 踩坑记录 # Setp : 移除旧版本Docker sudo apt-get remove docker docker-engine docker.io # Step ...

  5. 你真的了解字典(Dictionary)吗? C# Memory Cache 踩坑记录 .net 泛型 结构化CSS设计思维 WinForm POST上传与后台接收 高效实用的.NET开源项目 .net 笔试面试总结(3) .net 笔试面试总结(2) 依赖注入 C# RSA 加密 C#与Java AES 加密解密

    你真的了解字典(Dictionary)吗?   从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点.为了便于描述,我把上面 ...

  6. google nmt 实验踩坑记录

       最近因为要做一个title压缩的任务,所以调研了一些text summary的方法.    text summary 一般分为抽取式和生成式两种.前者一般是从原始的文本中抽取出重要的word o ...

  7. ABP框架踩坑记录

    ABP框架踩坑记录 ASP.NET Boilerplate是一个专用于现代Web应用程序的通用应用程序框架. 它使用了你已经熟悉的工具,并根据它们实现最佳实践. 文章目录 使用MySQL 配置User ...

  8. IDFA踩坑记录

    IDFA踩坑记录: 1.iOS10.0 以下,即使打开“限制广告跟踪”,依然可以读取idfa: 2.打开“限制广告跟踪”,然后再关闭“限制广告跟踪”,idfa会改变: 3.越狱机器安装开发证书打的包, ...

  9. 复杂业务下向Mysql导入30万条数据代码优化的踩坑记录

    从毕业到现在第一次接触到超过30万条数据导入MySQL的场景(有点low),就是在顺丰公司接入我司EMM产品时需要将AD中的员工数据导入MySQL中,因此楼主负责的模块connector就派上了用场. ...

随机推荐

  1. Spring学习之旅(八)Spring 基于AspectJ注解配置的AOP编程工作原理初探

    由小编的上篇博文可以一窥基于AspectJ注解配置的AOP编程实现. 本文一下未贴出的相关代码示例请关注小编的上篇博文<Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AO ...

  2. Ubuntu-Tweak 安装

    Ubuntu Tweak 是中国人开发的一款专门为Ubuntu准备的配置.调整工具,类似与compiz,界面更友好.   下面是安装命令:   第一步:添加tweak源 sudo add-apt-re ...

  3. 函数纹理(国际象棋棋盘纹理&粗布纹理)MFC

    函数纹理(国际象棋棋盘纹理&粗布纹理)MFC实现  源码百度云下载 国际象棋棋盘纹理(效果图见最后) //国际象棋纹理函数 //g(u, v) = a , 向下取整(8u)+向下取整(8v) ...

  4. Hive内部表与外部表的区别

    1.未被external修饰的是内部表[managed table],被external修饰的为外部表[external table]. 2.内部表数据由Hive自身管理,外部表数据由HDFS管理. ...

  5. MSSQL-sql server-视图简介

    转自:http://www.maomao365.com/?p=4511 一.视图简介 视图在MSSQL中是一张虚拟表. 视图的数据由sql语句定义生成,视图中指定新生成数据的列名称和数据格式,视图中的 ...

  6. Sqlserver还原master

    net stop mssqlserver net start mssqlserver /m"SQLCMD" sqlcmd -s xx sqlcmd -s xx -U sa -P x ...

  7. Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist

    今天在用一键安装mysql的shell脚本安装mysql-5.1.73软件后发现mysql始终无法启动,多次执行后依旧报错,只能去查看error日志,发现了如下的2个错误: 错误一:Fatal err ...

  8. powershell脚本之windows服务与进程

    powershell脚本之windows服务与进程 服务与进程的区别: Windows服务是指系统自动完成的,不需要和用户交互的过程,可长时间运行的可执行应用程序 进程是程序运行的实例,系统会给运行中 ...

  9. February 18th, 2018 Week 8th Sunday

    Don't cry for what is lost. Smile for what still remains. 别为失去的哭泣,为还留在你身边的一切微笑吧. I have been told th ...

  10. ESLint笔记

    ESLint是JavaScript的代码检查工具.因为JS是弱类型的语言,不需要编译,代码错误是在运行时调适的,所以需要个工具在编码的过程发现问题.ESLint的初衷是为了让程序员可以创建自己的检测规 ...