`
YYZhQ
  • 浏览: 17572 次
文章分类
社区版块
存档分类
最新评论

Apache Shiro 配置

 
阅读更多

Apache Shiro 配置

Shiro 可以在任何环境下工作,从简单的命令行程序到大型企业级集群项目,因为环境的多样化,可以通过许多途径来配合当前环境的配置方式进行配置,在本章我们来了解一下shiro核心支持的配置方式。

多样的配置选项:

ShiroSecurityManager和其它支持组件都和JavaBean兼容,所以Shiro几乎可以用任何方式进行配置,比如JavaXMLSpring, JBoss, Guice, 等等),YAML JSON,Groovy Builder markup等。

在程序中配置

创建一个SecurityManager并使之可用最简单的方法就是创建一个org.apache.shiro.mgt.DefaultSecurityManager 对象并写将它写入代码,例如:

Realm realm = //instantiate or acquire a Realm instance. We'll discuss Realms later.

SecurityManager securityManager = new DefaultSecurityManager(realm);

//Make the SecurityManager instance available to the entire application via static memory:

SecurityUtils.setSecurityManager(securityManager);

仅仅三行代码,你就可以拥有一个适用于任何程序的功能全面的shiro环境,多么简单。

SecurityMangger Object Graph

如同我们在架构(Architecture)中讨论过的,Shiro SecurityMangger 本质上是一个由一套安全组件组成的对象模块视图(graph),因为与JavaBean兼容,所以可以对所有这些组件调用的getter setter 方法来配置SecurityManager和它的内部对象视图。

例如,你想用一个自定义的SessionDAO来定制Session Management从而配置一个SecurityManager 实例,你就可以使用SessionManagersetSessionDAO方法直接set这个SessionDAO

...

DefaultSecurityManager securityManager = new DefaultSecurityManager(realm);

SessionDAO sessionDAO = new CustomSessionDAO();

((DefaultSessionManager)securityManager.getSessionManager()).setSessionDAO(sessionDAO);

...

使用这些函数,你可以配置SecurityManager视图(graph)中的任何一部分。

虽然在程序中配置很简单,但它并不是我们现实中配置的完美解决方案。在几种情况下这种方法可能并不适合你的程序:

它需要你确切知道并实例化一个直接实现(direct implementation),然而更好的做法是你并不需要知道这些实现也不需要知道从哪里找到它们。

因为JAVA类型安全的特性,你必须对通过get*获取的对象进行强制类型转换,这么多强制转换非常的丑陋、累赘并且会和你的类紧耦合。

SecurityUtils.setSecurityManager方法会将SecurityManager实例化为虚拟机的单独静态实例,在大多数程序中没有问题,但如果有多个使用shiro的程序在同一个JVM中运行时,各程序有自己独立的实例会更好些,而不是共同引用一块静态内存。

改变配置就需要重新编译你的程序。

然而,尽管有这些不足,在程序中定制的这种方法在限制内存(memory-constrained )的环境中还是很有价值的,像智能电话程序。如果你的程序不是运行在一个限制内存的环境中,你会发现基于文本的配置会更易读易用。

INI 配置

大多数程序已经改为使用基于文本的配置,不需要依靠代码就可进行修改,对于不熟悉shiro API的人来说,也易于理解。

为了确保具有共性的基于文本配置的途径适用于任何环境而且减少对第三方的依赖,shiro支持使用INI创建SecurityManager对象视图(graph)以及它支持的组件,INI易读易配置,很容易创建并且对大多数程序都很适合。

通过INI资源创建SecurityManager

这里举两个通过INI配置创建SecurityManager的例子。

INI资源创建SecurityManager

我们可以从一个INI资源路径创建一个SecurityManager实例,资源可以通过文件系统(前缀为file:)、类路径(classpath:)或者URL(url:)获得,下面的例子使用一个Factory从类路径根目录加载shiro.ini并返回一个SecurityManager实例。

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.util.Factory;

import org.apache.shiro.mgt.SecurityManager;

import org.apache.shiro.config.IniSecurityManagerFactory;

...

Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

SecurityManager securityManager = factory.getInstance();

SecurityUtils.setSecurityManager(securityManager);

通过INI实例创建SecurityManager

INI配置可以通过org.apache.shiro.config.Ini 类用程序方式创建,这个INI类类似于JDKjava.util.Properties类,但支持通过section名分割。例子如下:

import org.apache.shiro.SecurityUtils;

import org.apache.shiro.util.Factory;

import org.apache.shiro.mgt.SecurityManager;

import org.apache.shiro.config.Ini;

import org.apache.shiro.config.IniSecurityManagerFactory;

...

Ini ini = new Ini();

//populate the Ini instance as necessary

...

Factory<SecurityManager> factory = new IniSecurityManagerFactory(ini);

SecurityManager securityManager = factory.getInstance();

SecurityUtils.setSecurityManager(securityManager);

现在我们知道如何使用INI配置文件创建一个SecurityManager,让我们仔细了解一下如何定义一个shiro INI配置文件。

INI Sections

INI 基于文本配置,在独立命名的区域内通过成对的键名/键值组成。键名在每个区域内必须唯一,但在整个配置文件中并不需要这样(这点和JDKProperties不同),每一个区域(section)可以看作是一个独立的Properties 定义。

注释行可以用“#”或“;”标识。

这里是一个shiro可以理解的各section的示例。

# =======================

# Shiro INI configuration

# =======================

[main]

# Objects and their properties are defined here,

# Such as the securityManager, Realms and anything

# else needed to build the SecurityManager

[users]

# The 'users' section is for simple deployments

# when you only need a small number of statically-defined

# set of User accounts.

[roles]

# The 'roles' section is for simple deployments

# when you only need a small number of statically-defined

# roles.

[urls]

# The 'urls' section is used for url-based security

# in web applications. We'll discuss this section in the

# Web documentation

[main]

[main]区域是配置程序SecurityManager实例及其支撑组件的地方,如Realm

通过INI配置像SecurityManager的对象实例及其支撑组件听起来是一件很困难的事情,因为在这里我们只能用键名/键值对。但通过定义一些对象视图(graphs)可以理解的惯例,你发现你完全可以这样做。shiro利用这些假定的惯例来实现一个简单而简明的配置途径。

我们经常将这种方法认为是“可怜人的(poor man's)”的依赖注入,虽然不及成熟的Spring/Guice/JBossXML文件强大,但你会发现它可以做很多事情而且并不复杂,当然当那配置途径也可以使用,但对shiro来讲并不是必须的。

仅仅吊一下胃口,这里是一个简单的可以使用的[main]配置,下面我们会详细介绍,但你可能发现你仅凭直觉就可以理解一些。

sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher

myRealm = com.company.security.shiro.DatabaseRealm

myRealm.connectionTimeout = 30000

myRealm.username = jsmith

myRealm.password = secret

myRealm.credentialsMatcher = $sha256Matcher

securityManager.sessionManager.globalSessionTimeout = 1800000

定义一个对象

[main]中包含以下片段。

[main]

myRealm = com.company.shiro.realm.MyRealm

...

这一行实例化了一个类型为com.company.shiro.realm.MyRealm 的对象实例并且使对象使用myRealm作为名称以便于将来引用和配置。

如果对象实例化时实现了 org.apache.shiro.util.Nameable 接口,Nameable.setName方法将被以该名(在此例中为myRealm)命名的对象调用。

设置对象属性

原始值

简单的原始值属性可以使用下面的等于符号进行设置:

...

myRealm.connectionTimeout = 30000

myRealm.username = jsmith

...

这些配置行转换为方法调用就是:

...

myRealm.setConnectionTimeout(30000);

myRealm.setUsername("jsmith");

...

怎么做到的呢?它假定所有对象都是兼容JavaBeanPOJO。在设置这些属性时,Shiro默认使用Apache通用的BeanUtils来完成这项复杂的工作,所以虽然INI值是文本,BeanUtils知道如何将这些字符串值转换为适合的原始值类型并调用合适的JavaBeanssetter方法。

引用值

如果你想设置的值并不是一个原始值,而是另一个对象怎么办呢?你可以使用一个$符来引用一个之前定义的实例,如:

...

sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher

...

myRealm.credentialsMatcher = $sha256Matcher

...

这定义了名为sha256Matcher的对象并且使用BeanUtils将其设置到myRealm的实例中(通过调用 myRealm.setCredentialsMatcher(sha256Matcher) 方法)。

嵌套属性

通过在等号左侧使用点符号,你可以得到你希望设置对象视图最终的对象/属性,例如下面这行配置:

...

securityManager.sessionManager.globalSessionTimeout = 1800000

...

转换逻辑为(通过BeanUtils):

securityManager.getSessionManager().setGlobalSessionTimeout(1800000);

用这种方法访问的层数需要多深可以有多深:

object.property1.property2....propertyN.value = blah

BeanUtils 属性支持

BeanUtils支持任何指定的属性操作,在shiro[main]区域中setProperty方法将被调用,包括集合(set/列表(list/图(map),查看Apache Commons BeanUtils Website和文档了解更多的信息。

字节数组值

因为原始的字节数组不能直接在文本中定义,我们必须使用字节数组的文本编码。可以使用64位编码(默认)或者16位编码,默认为64位编码因为使用64位编码实际文字会少一些--它拥有很大的编码表,这意味着你的标识会更短(对于文本配置来讲会好一些)。

# 'cipherKey' 属性是一个字节数组,默认的, 字节数组属性被编码为64位的文本值

securityManager.rememberMeManager.cipherKey = kPH+bIxk5D2deZiIxcaaaA==

如果你想使用16位编码,你必须在字串前面加上0x前缀:

securityManager.rememberMeManager.cipherKey= 0x3707344A4093822299F31D008

集合属性

列表(Lists)、集合(Sets)、图(Maps)可以像其它属性一样设置--直接设置或者像嵌套属性一样,对于列表和集合,只需指定一个逗号分割的值集或者对象引用集。

如定义一些SessionListeners

sessionListener1 = com.company.my.SessionListenerImplementation

...

sessionListener2 = com.company.my.other.SessionListenerImplementation

...

securityManager.sessionManager.sessionListeners = $sessionListener1, $sessionListener2

对于图(Maps),你可以指定以逗号分割的键-值对列表,每个键-值之间用冒号分割:

object1 = com.company.some.Class

object2 = com.company.another.Class

...

anObject = some.class.with.a.Map.property

anObject.mapProperty = key1:$object1, key2:$object2

在上面的例子中,$object1 引用的对象将存于键key1之下,也就是map.get("key1")将返回object1。你也可以使用其它对象作为键值:

anObject.map = $objectKey1:$objectValue1, $objectKey2:$objectValue2

...

注意事项

顺序问题

上述INI格式和约定非常方便也非常易懂,但它并没有另外一种text/XML的配置路径强大,通过上述途径进行配置需要知道非常重要的一件事情就是顺序问题!

小心

每一个对象实例以及每一个指定的值都将按照其在[main]区域中产生的顺序的执行,这些行最终转换为JavaBeansgetter/setter方法调用,这些方法按同样的顺序调用。

当你写配置文件的时候要牢记于此。

覆盖实例

每一个对象都可以被后定义的新实例覆盖,例如,第二个myRealm定义将重写第一个:

...

myRealm = com.company.security.MyRealm

...

myRealm = com.company.security.DatabaseRealm

...

这样的结果是myRealmcom.company.security.DatabaseRealm实例而前面的实例不会被使用(会作为垃圾回收)。

默认Default SecurityManager

你可能注意到在以上所有例子中都没有定义SecurityManager,而我们直接设置其嵌套属性:

myRealm = ...

securityManager.sessionManager.globalSessionTimeout = 1800000

...

这是因为securityManager实例是特殊的--它已经为你实例化过了并且准备好了,所以你并不需要知道指定的实例化SecurityManager的实现类。

当然,如果你确实想指定你自己的实现类,你可以像上面的覆盖实例那样定义你自己的实现:

...

securityManager = com.company.security.shiro.MyCustomSecurityManager

...

当然,很少需要这样--shirosecurityManager实现可以按需求进行定制,你可能要问一下自己(或者用户群)你是否真的需要这样做。

[users]

[users]区域允许你定义一组静态的用户帐号,这对于那些只有少数用户帐号并且用户帐号不需要在运行时动态创建的环境来说非常有用。下面是一个例子:

[users]

admin = secret

lonestarr = vespa, goodguy, schwartz

darkhelmet = ludicrousspeed, badguy, schwartz

自动生成IniRealm

定义非空的[users][roles]区域将自动创建org.apache.shiro.realm.text.IniRealm实例,[main]区域下生成一个可用的iniRealm,你可以像上面配置其它对象那样配置它。

格式

[users]区域下每一行必须和下面的形式一致:

username = password, roleName1, roleName2, ..., roleNameN

等号左边的值是用户名;

等号右侧第一个值是用户密码,密码是必须的;

密码之后用逗号分割的值是赋予用户的角色名,角色名是可选的。

密码加密

如果你不希望[users]区域下的密码以明文显示,你可以用你喜欢的哈希算法(MD5, Sha1, Sha256, 等)来加密它们,将加密后的字符串作为密码值,默认的,密码建议用16位编码算法,但也可以用64位编码算法替代(如下)。

简单的安全密码

为了节约时间获得最佳实践,你可以使用shiroCommand Line Hasher,它可以加密密码和其它类型的资源,尤其使给INI[user]密码加密变得非常简单。

一旦你指定了加密后的密码值,你必须告诉shiro它们是加密的,你可以通过配置配置在[main]隐含创建的iniRealm相应的CredentialsMatcher实现来告知你使用的哈希算法:

[main]

...

sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher

...

iniRealm.credentialsMatcher = $sha256Matcher

...

[users]

# user1 = sha256-hashed-hex-encoded password, role1, role2, ...

user1 = 2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b, role1, role2, ...

你可以像配置其他对象那样配置CredentialsMatcher的所有属性,例如,指定使用salting或者有多少hash iterations执行,可以查看org.apache.shiro.authc.credential.HashedCredentialsMatcher Java文档更好地理解hashing策略,可能会很有帮助。

例如,如果你用64位编码方式取代了16位编码方式,你应该指定:

[main]

...

# true = hex, false = base64:

sha256Matcher.storedCredentialsHexEncoded = false

[roles]

[roles]区域允许你将权限和在[users]定义的角色对应起来,同样的,这对于那些只有少数用户帐号并且用户帐号不需要在运行时动态创建的环境来说非常有用。下面是一个例子:

[roles]

# 'admin' role has all permissions, indicated by the wildcard '*'

admin = *

# The 'schwartz' role can do anything (*) with any lightsaber:

schwartz = lightsaber:*

# The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with

# license plate 'eagle5' (instance specific id)

goodguy = winnebago:drive:eagle5

格式

[roles]区域下的每一行必须用下面的格式定义角色-权限的键/值对应关系。

rolename = permissionDefinition1, permissionDefinition2, ..., permissionDefinitionN

权限定义可以是非常随意的字符串,但大部分用户还是希望使用易用而灵活的和 org.apache.shiro.authz.permission.WildcardPermission 形式一致的字符串格式。查看Permissions文档获取更多关于权限的信息和你可以如何利用它为你服务。

内部用法

注意如果一个特定的权限定义需要用到逗号分隔(如:printer:5thFloor:print,info),你需要将该定义用双引号括起来从而避免出错:"printer:5thFloor:print,info"

没有权限的角色

如果你有不需要权限的角色,不需要将它们列入[roles]区域,仅仅在 [users]区域定义角色名就可以创建它们(如果它们尚不存在)。

[urls]

该区域选项将在web章节讨论。

为文档加把手

我们希望这篇文档可以帮助你使用Apache Shiro进行工作,社区一直在不断地完善和扩展文档,如果你希望帮助shiro项目,请在你认为需要的地方考虑更正、扩展或添加文档,你提供的任何点滴帮助都将扩充社区并且提升Shiro

提供你的文档的最简单的途径是将它发送到用户论坛(http://shiro-user.582556.n2.nabble.com/)或邮件列表(http://shiro.apache.org/mailing-lists.html

原文地址:http://shiro.apache.org/configuration.html

分享到:
评论

相关推荐

    Apache Shiro教程

    通过这个Apache Shiro教程,你可以学习到如何构建安全的Java应用,了解Shiro的配置和用法,以及如何在实际项目中实施身份验证、授权、会话管理和加密策略。无论你是初学者还是经验丰富的开发者,Shiro都是一个值得...

    Apache shiro 1.13.0源码

    在 web 应用中,可以通过配置 `shiro.ini` 或者 `Web.xml` 来定制过滤器。 6. **Caching**:Shiro 支持缓存管理,可以缓存认证和授权信息,提高性能。 7. **Testing**:源码中包含了测试用例,帮助开发者理解和...

    apache shiro 管理用户权限与数据库交互

    Apache Shiro是一个强大且易用的Java安全框架,它提供了身份验证、授权、加密和会话管理等功能。本文将深入探讨如何使用Apache Shiro管理用户权限,并与数据库进行交互,以便实现动态、灵活的安全策略。 ### 一、...

    Apache_Shiro_使用手册(一)Shiro架构介绍

    ### Apache Shiro 使用手册(一)Shiro架构介绍 #### 一、Shiro简介 Apache Shiro 是一款功能强大且易于使用的 Java 安全框架,它提供了多种安全相关的功能和服务,包括但不限于认证、授权、加密和会话管理。相较...

    SpringBoot + Apache Shiro + Mybatis Plus + Thymeleaf 实现的内容管理系统

    采用SpringBoot + Apache Shiro + Mybatis Plus + Thymeleaf 实现的内容管理系统(附带权限管理),是搭建博客、网站的不二之选。 技术栈:Spring Boot、Apache Shiro、MyBatis-Plus、Alibaba Druid、Redis、MySQL、...

    Apache Shiro 集成-spring

    2. 配置Shiro:创建Shiro配置文件(如shiro.ini或shiro.xml),定义安全策略、过滤器链等。 3. 创建安全组件:包括Subject、Realms(负责从数据源获取用户信息)、Filters(过滤器)等。 4. 集成Spring:通过Spring...

    让Apache Shiro保护你的应用

    1. **易于使用**:Apache Shiro将易用性作为首要目标之一,简化了安全配置和管理流程,使得即使是初学者也能快速上手。 2. **广泛的适用范围**:Shiro能够满足各种类型应用的安全需求,无论是Web应用、移动应用还是...

    Apache shiro权限控制基础配置代码

    以下是一个简单的Shiro配置示例,展示了如何创建 Realm 和配置 Security Manager: ```java public class MyRealm extends AuthorizingRealm { // 实现认证和授权逻辑 } @Configuration public class ShiroConfig...

    spring mvc、apache shiro、mysql 框架搭建,基于maven构建

    3. 实现Apache Shiro的安全配置,如 Realm、Session管理和Filter链,以实现用户认证和授权。 4. 设计数据库模型,编写SQL语句,配置数据源连接,使用ORM框架如MyBatis进行数据操作。 5. 编写Controller层处理HTTP...

    Apache Shiro中文版使用手册

    - **Realm**:领域,充当 Shiro 与应用程序安全数据之间的桥梁,负责从配置的数据源中检索用户及权限信息。 **2.2 其他重要组件** - **Authenticator**:认证器,负责用户的身份验证工作,验证用户提供的凭证信息...

    apache shiro 实例

    Apache Shiro 是一个强大且易用的Java安全框架,它提供了认证、授权、加密和会话管理功能,简化了企业级应用的安全实现。本实例将深入探讨 Apache Shiro 的核心概念和常见用法。 1. **认证**:Shiro 提供了用户身份...

    Apache Shiro 使用手册(五) Shiro 配置说明

    ### Apache Shiro 配置说明详解 #### 一、引言 Apache Shiro 是一个强大且易用的 Java 安全框架,它提供了认证、授权、加密和会话管理等功能,能够帮助开发者轻松地处理非常复杂的安全问题。本文将重点介绍 Shiro ...

    shiro最简单整合版本

    以上就是 Apache Shiro 的最简单整合版本,它涵盖了基本的身份认证、授权流程和配置。然而,实际项目中可能需要考虑更多细节,如会话管理、缓存策略、Web 应用的集成等。Shiro 提供了丰富的 API 和扩展点,可以根据...

    Spring MVC+Mybatis+Ehcache+Apache Shiro+Bootstrap整合开发java仓库管理系统源码

    - 配置Apache Shiro,创建安全配置,定义 Realm 进行身份验证和授权,设置过滤链以控制访问权限。 - 将Bootstrap样式和JavaScript库引入到项目中,根据需求定制和布局前端页面。 这个仓库管理系统源码是一个综合性...

    apache shiro文档

    Apache Shiro 是一个强大且易用的 Java 安全框架,它提供了认证、授权、加密和会话管理功能,可以非常方便地为应用程序提供安全保障。本文档合集包含了多个 PDF 文件,全面覆盖了 Apache Shiro 的核心概念和使用方法...

    整合Apache Oltu 与 Shiro. 提供一个轻量的OAUTH2应用框架

    3. 在Shiro配置中,设置OAuth2过滤器,拦截请求并使用Oltu验证令牌。 4. 在应用程序中,根据需求选择合适的OAuth2 grant类型,如授权码模式或资源所有者密码凭证模式。 5. 对于移动设备,可能还需要配置客户端应用以...

    apache-shiro教程完整版.7z

    Apache Shiro 是一个强大且易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可以非常轻松地开发出足够安全的应用。张开涛的《跟我学Shiro》是一本深入浅出的教程,旨在帮助读者快速掌握Shiro的核心概念...

    spring boot+mybatis+thymeleaf+apache shiro开发面向学习型的后台管理系统

    7. **Shiro配置**:配置Shiro的 Realm,实现用户认证和授权逻辑。 通过以上组件的协同工作,该后台管理系统能够提供用户注册、登录、角色管理、权限分配等功能,为学习资源的管理和共享提供了便捷的平台。同时,...

    Spring Boot+Maven+Spring Data JPA+apache Shiro+Easyui实现通用用户权限管理系统

    本项目基于"Spring Boot+Maven+Spring Data JPA+apache Shiro+Easyui",这些技术栈的选择旨在简化开发过程,提供强大的功能,并确保系统的安全性和用户体验。 1. **Spring Boot**: Spring Boot是Spring框架的简化版...

    shiro1.7.1.zip

    Apache Shiro是一个强大的Java安全框架,它...此外,了解并正确配置Shiro的各个组件,如Realms(用于认证和授权的数据源)、Filters(处理HTTP请求的过滤器)和Cryptography(加密工具),是实现高效且安全应用的关键。

Global site tag (gtag.js) - Google Analytics