4.1 根对象SecurityManager

从之前的Shiro架构图可以看出,Shiro是从根对象SecurityManager进行身份验证和授权的;也就是所有操作都是自它开始的,这个对象是线程安全且真个应用只需要一个即可,因此Shiro提供了SecurityUtils让我们绑定它为全局的,方便后续操作。

因为Shiro的类都是POJO的,因此都很容易放到任何IoC容器管理。但是和一般的IoC容器的区别在于,Shiro从根对象securityManager开始导航;Shiro支持的依赖注入:public空参构造器对象的创建、setter依赖注入。

1、纯Java代码写法(com.github.zhangkaitao.shiro.chapter4.NonConfigurationCreateTest):

  1. DefaultSecurityManager securityManager = new DefaultSecurityManager();
  2. //设置authenticator
  3. ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
  4. authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
  5. securityManager.setAuthenticator(authenticator);
  6. //设置authorizer
  7. ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
  8. authorizer.setPermissionResolver(new WildcardPermissionResolver());
  9. securityManager.setAuthorizer(authorizer);
  10. //设置Realm
  11. DruidDataSource ds = new DruidDataSource();
  12. ds.setDriverClassName("com.mysql.jdbc.Driver");
  13. ds.setUrl("jdbc:mysql://localhost:3306/shiro");
  14. ds.setUsername("root");
  15. ds.setPassword("");
  16. JdbcRealm jdbcRealm = new JdbcRealm();
  17. jdbcRealm.setDataSource(ds);
  18. jdbcRealm.setPermissionsLookupEnabled(true);
  19. securityManager.setRealms(Arrays.asList((Realm) jdbcRealm));
  20. //将SecurityManager设置到SecurityUtils 方便全局使用
  21. SecurityUtils.setSecurityManager(securityManager);
  22. Subject subject = SecurityUtils.getSubject();
  23. UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
  24. subject.login(token);
  25. Assert.assertTrue(subject.isAuthenticated());

2.1、等价的INI配置(shiro-config.ini)

  1. [main]
  2. #authenticator
  3. authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
  4. authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
  5. authenticator.authenticationStrategy=$authenticationStrategy
  6. securityManager.authenticator=$authenticator
  7. #authorizer
  8. authorizer=org.apache.shiro.authz.ModularRealmAuthorizer
  9. permissionResolver=org.apache.shiro.authz.permission.WildcardPermissionResolver
  10. authorizer.permissionResolver=$permissionResolver
  11. securityManager.authorizer=$authorizer
  12. #realm
  13. dataSource=com.alibaba.druid.pool.DruidDataSource
  14. dataSource.driverClassName=com.mysql.jdbc.Driver
  15. dataSource.url=jdbc:mysql://localhost:3306/shiro
  16. dataSource.username=root
  17. #dataSource.password=
  18. jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
  19. jdbcRealm.dataSource=$dataSource
  20. jdbcRealm.permissionsLookupEnabled=true
  21. securityManager.realms=$jdbcRealm

即使没接触过IoC容器的知识,如上配置也是很容易理解的:

1、对象名=全限定类名  相对于调用public无参构造器创建对象

2、对象名.属性名=值    相当于调用setter方法设置常量值

3、对象名.属性名=$对象引用    相当于调用setter方法设置对象引用

2.2、Java代码(com.github.zhangkaitao.shiro.chapter4.ConfigurationCreateTest)

  1. Factory<org.apache.shiro.mgt.SecurityManager> factory =
  2. new IniSecurityManagerFactory("classpath:shiro-config.ini");
  3. org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
  4. //将SecurityManager设置到SecurityUtils 方便全局使用
  5. SecurityUtils.setSecurityManager(securityManager);
  6. Subject subject = SecurityUtils.getSubject();
  7. UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
  8. subject.login(token);
  9. Assert.assertTrue(subject.isAuthenticated());

如上代码是从Shiro INI配置中获取相应的securityManager实例:

1、默认情况先创建一个名字为securityManager,类型为org.apache.shiro.mgt.DefaultSecurityManager的默认的SecurityManager,如果想自定义,只需要在ini配置文件中指定“securityManager=SecurityManager实现类”即可,名字必须为securityManager,它是起始的根;

2、IniSecurityManagerFactory是创建securityManager的工厂,其需要一个ini配置文件路径,其支持“classpath:”(类路径)、“file:”(文件系统)、“url:”(网络)三种路径格式,默认是文件系统;

3、接着获取SecuriyManager实例,后续步骤和之前的一样。

从如上可以看出Shiro INI配置方式本身提供了一个简单的IoC/DI机制方便在配置文件配置,但是是从securityManager这个根对象开始导航。

4.2 INI配置

ini配置文件类似于Java中的properties(key=value),不过提供了将key/value分类的特性,key是每个部分不重复即可,而不是整个配置文件。如下是INI配置分类:

  1. [main]
  2. #提供了对根对象securityManager及其依赖的配置
  3. securityManager=org.apache.shiro.mgt.DefaultSecurityManager
  4. …………
  5. securityManager.realms=$jdbcRealm
  6. [users]
  7. #提供了对用户/密码及其角色的配置,用户名=密码,角色1,角色2
  8. username=password,role1,role2
  9. [roles]
  10. #提供了角色及权限之间关系的配置,角色=权限1,权限2
  11. role1=permission1,permission2
  12. [urls]
  13. #用于web,提供了对web url拦截相关的配置,url=拦截器[参数],拦截器
  14. /index.html = anon
  15. /admin/** = authc, roles[admin], perms["permission1"]

[main]部分

提供了对根对象securityManager及其依赖对象的配置。

创建对象

  1. securityManager=org.apache.shiro.mgt.DefaultSecurityManager

其构造器必须是public空参构造器,通过反射创建相应的实例。

 

常量值setter注入

  1. dataSource.driverClassName=com.mysql.jdbc.Driver
  2. jdbcRealm.permissionsLookupEnabled=true

会自动调用jdbcRealm.setPermissionsLookupEnabled(true),对于这种常量值会自动类型转换。

 

对象引用setter注入

  1. authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
  2. authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
  3. authenticator.authenticationStrategy=$authenticationStrategy
  4. securityManager.authenticator=$authenticator

会自动通过securityManager.setAuthenticator(authenticator)注入引用依赖。

嵌套属性setter注入

  1. securityManager.authenticator.authenticationStrategy=$authenticationStrategy

也支持这种嵌套方式的setter注入。

byte数组setter注入

  1. #base64 byte[]
  2. authenticator.bytes=aGVsbG8=
  3. #hex byte[]
  4. authenticator.bytes=0x68656c6c6f

默认需要使用Base64进行编码,也可以使用0x十六进制。

Array/Set/List setter注入

  1. authenticator.array=1,2,3
  2. authenticator.set=$jdbcRealm,$jdbcRealm

多个之间通过“,”分割。

Map setter注入

  1. authenticator.map=$jdbcRealm:$jdbcRealm,1:1,key:abc

即格式是:map=key:value,key:value,可以注入常量及引用值,常量的话都看作字符串(即使有泛型也不会自动造型)。

实例化/注入顺序

  1. realm=Realm1
  2. realm=Realm12
  3. authenticator.bytes=aGVsbG8=
  4. authenticator.bytes=0x68656c6c6f

后边的覆盖前边的注入。

测试用例请参考配置文件shiro-config-main.ini。

[users]部分

配置用户名/密码及其角色,格式:“用户名=密码,角色1,角色2”,角色部分可省略。如:

  1. [users]
  2. zhang=123,role1,role2
  3. wang=123

密码一般生成其摘要/加密存储,后续章节介绍。

[roles]部分

配置角色及权限之间的关系,格式:“角色=权限1,权限2”;如:

  1. [roles]
  2. role1=user:create,user:update
  3. role2=*

如果只有角色没有对应的权限,可以不配roles,具体规则请参考授权章节。

[urls]部分

配置url及相应的拦截器之间的关系,格式:“url=拦截器[参数],拦截器[参数],如:

  1. [urls]
  2. /admin/** = authc, roles[admin], perms["permission1"]

具体规则参见web相关章节。

shiro中INI配置的更多相关文章

  1. Apache shiro集群实现 (二) shiro 的INI配置

    Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...

  2. 第四章:shiro的INI配置

    4.1 根对象SecurityManager 从之前的Shiro架构图可以看出,Shiro是从根对象SecurityManager进行身份验证和授权的:也就是所有操作都是自它开始的,这个对象是线程安全 ...

  3. shiro中anon配置不生效

    再配置shiro的时候,如下代码要注意: 1.下述代码中必须是LinkedHashMap 而不能是HashMap. 2.anon定义必须在authc之前 否则anon定义不生效   @Bean     ...

  4. Shiro中Realm

    6.1 Realm [2.5 Realm]及[3.5 Authorizer]部分都已经详细介绍过Realm了,接下来再来看一下一般真实环境下的Realm如何实现. 1.定义实体及关系   即用户-角色 ...

  5. 跟开涛老师学shiro -- INI配置

    之前章节我们已经接触过一些INI配置规则了,如果大家使用过如spring之类的IoC/DI容器的话,Shiro提供的INI配置也是非常类似的,即可以理解为是一个IoC/DI容器,但是区别在于它从一个根 ...

  6. shiro.ini 配置详解

    引用: [1]开涛的<跟我学shiro> [2]<SpringMVC整合Shiro> [3]<shiro简单配置> [4]Apache shiro集群实现 (一) ...

  7. Shiro ini配置

    Shiro.ini配置: ini配置文件类似Java中的properties(key = value),不过提供了key/value分类的特性,每个部分的key不重复即可 在eclipse中设置打开方 ...

  8. 第四章 INI配置——《跟我学Shiro》

    转发地址:https://www.iteye.com/blog/jinnianshilongnian-2020820 第四章 INI配置——<跟我学Shiro> 博客分类: 跟我学Shir ...

  9. Shiro学习(4)INI配置

    之前章节我们已经接触过一些INI配置规则了,如果大家使用过如spring之类的IoC/DI容器的话,Shiro提供的INI配置也是非常类似的,即可以理解为是一个IoC/DI容器,但是区别在于它从一个根 ...

随机推荐

  1. 题解——code[vs] 1506 传话(传递闭包)

    裸的传递闭包 直接Floyd暴力即可 #include <cstdio> #include <algorithm> #include <cstring> using ...

  2. 什么情况下用断言?assert

    可以再预计正常情况下不会到达的任何位置上放置断言,断言可以用于验证传递给私有方法的参数.不俺的参数过,断言不应该用于验证传递给公有方法的参数,因为不管是否启用了断言,公有方法都必须检查其参数.不过,既 ...

  3. Git-Flow | How it’s used and why you should

    Git-Flow | How it’s used and why you should What is Git-Flow about? Git-Flow is a workflow for using ...

  4. Docker save & load

    docker save Estimated reading time: 1 minute Description Save one or more images to a tar archive (s ...

  5. HDU 5236 Article(概率DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=5236 题意:现在有人要在文本编辑器中输入n个字符,然而这个编辑器有点问题. 在i+0.1s(i>=0)的时 ...

  6. 基于 Python 和 Pandas 的数据分析(3) --- 输入/输出 基础

    这一节, 我们要讨论 Pandas 的输入与输出, 并且应用在现实的实际例子中. 为了得到大量的数据, 向大家推荐一个网站 Quandl. Quandl 有很多免费和付费的资源. 这个网站最大的优势在 ...

  7. git 命令 clone分支的代码

    一个项目通常含有很多分支, master分支一般是经过测试,验证没有问题后,代码才会提交到master分支 develop分支,是测试经常拉下来进行测试的分支 直接复制develop分支的git 命令 ...

  8. sqlserver 中常见的函数 数学函数

    create table testnum( ID int identity(1,1), num float) insert testnum values (1) insert testnum valu ...

  9. Jtest的简单使用

    Jtest主要用于快速测试自己的代码是否正确 条件,导入相应的Jtest包 @Test    public void test() {        System.out.println(" ...

  10. [osg]osg绘制动态改变顶点的几何体

    最简单的顶点数据更新方法是预先获取setVertexArray()所用的数组数据,并对其进行更新.但是对于开启显示列表支持的几何体(这是默认的情况)来说,有一个问题需要特别需要引起注意,即显示列表中的 ...