📄 acegi (version1_0_4)中文参考手册 [转载自 dxjsunday] - 懒散狂徒的专栏 - csdnblog.htm
字号:
上,你的Java虚拟机需要进行配置,将授予不同Java类型的权限最小化,然后,你的应用程序要对添加针对自身特定问题域的安全配置。Acegi
Security使后者-应用程序安全变得容易。
<BR>当然,你要正确对待上述提到的每个安全层,以及包含于每个层的管理因素。这样的管理因素具体包括:安全公告监测,补丁,人工诊断,审计,变更管理,工程管理系统,数据备份,灾难恢复,性能评测,负载监测,集中日志,应急反应程序等等。
<BR>Acegi
Security专注于在企业应用安全层为您提供帮助,你将会发现和各式各样的需求和商业问题领域一样多。银行系统的需求和电子商务应用的需求不同。电子
商务应用和售卖军用自动工具的公司的需求不同。这些客户化的需求使得应用安全显得有趣,富有挑战性而且物有所值。 <BR>本手册为Acegi Security
1.0.0的发布而大规模重新组织。请先阅读Part I 架构概览。手册的其余部分按照传统的手册方式编排,需要一定的基础才能阅读。
<BR>我们希望您会觉得手册有用,并且欢迎您提供反馈意见和建议。 <BR>最后,欢迎加入Acegi Security社区。
<BR>acegi参考手册(v1.0.4)[译]-第一章 简介 <BR>Part I. 架构概览 <BR>象其他的软件一样,Acegi
Security也有在整个框架中都会使用的特定核心接口,类,和概念抽象。在手册的这一部分,在检视这些规划和执行Acegi
Security集成所必须的核心要素之前,我们先介绍Acegi Security。 <BR><BR>第一章. 简介 <BR>1.1. Acegi
Security是什么? <BR>Acegi
Security为基于J2EE的企业软件应用提供全面的安全服务。特别是使用领先的J2EE解决方案-Srping框架开发的项目。如果您不是使用
Spring开发企业应用,我们温馨提醒您仔细研究一下。熟悉Spring,尤其是依赖注射原理,会极大的帮助你快速掌握Acegi Security。
<BR>人们使用Acegi Security有很多种原因,不过通常吸引他们到这个项目的原因是他们在J2EE的 Servlet Specification 或者
EJB Specification中找不到迫切需要的典型企业应用场景。提到这些规范,特别要提出的是他们不是在WAR或者EAR级别可移植的。这样,如果你切
换服务器环境,一般来说你要在目标环境中花费很多工夫来重新配置你的应用安全。使用Acegi
Security解决了这些问题,并且为你提供了很多其他有用的,完全可定制的安全特性。 <BR>如你所知,安全包含两个主要操作。第一个被称为“认
证”,是为用户建立一个它所声明的principal。Principal通常代表用户,设备,或者其他能在你的应用中执行操作的其他系统。“授权”指判
定一个principal能否在你的系统中执行某个操作。在到达授权判断之前,principal的的身份认证已经由认证过程执行过了。这些概念是通用
的,不是Acegi Security特有的。 <BR>在认证层面,Acegi
Security广泛支持各种认证模块。这些认证模块绝大多数是第三方提供,或者相关的标准组织开发的,例如Internet Engineering Task
Force。作为补充,Acegi Security自己也提供了一些认证功能。Acegi Security当前支持如下的认证技术。 <BR>&S226;
HTTP BASIC authentication headers (an IEFT RFC-based standard) <BR>&S226;
HTTP Digest authentication headers (an IEFT RFC-based standard) <BR>&S226;
HTTP X.509 client certificate exchange (an IEFT RFC-based standard)
<BR>&S226; LDAP (a very common approach to cross-platform authentication
needs, especially in large environments) <BR>&S226; Form-based
authentication (for simple user interface needs) <BR>&S226; Computer
Associates Siteminder <BR>&S226; JA-SIG Central Authentication Service
(otherwise known as CAS, which is a popular open source single sign on system)
<BR>&S226; Transparent authentication context propagation for Remote Method
Invocation (RMI) and HttpInvoker (a Spring remoting protocol) <BR>&S226;
Automatic "remember-me" authentication (so you can tick a box to avoid
re-authentication for a predetermined period of time) <BR>&S226; Anonymous
authentication (allowing every call to automatically assume a particular
security identity) <BR>&S226; Run-as authentication (which is useful if one
call should proceed with a different security identity) <BR>&S226; Java
Authentication and Authorization Service (JAAS) <BR>&S226; Container
integration with JBoss, Jetty, Resin and Tomcat (so you can still use Container
Manager Authentication if desired) <BR>&S226; 你自己的认证系统 (如下所示) <BR>很
多独立软件供应商(ISVs)选择Acegi
Security是因为它具有丰富的认证模块。这样无论他们的终端客户需要什么,他们都可以快速集成到他们的系统中,不用花很多工夫或者让终端客户改变环
境。如果Acegi Security System for Spring的7个认证模块还没有满足你的需求的话,Acegi
Security是一个开放的系统,很容易写你自己的认证机制。许多Acegi
Security的企业用户需要和“遗留”系统集成,这些遗留系统不遵循任何安全标准,Acegi Security能够和这样的系统“合作愉快”。 <BR>有
时候基本的认证是不够的。有时候你需要根据principal和应用交互的方式来应用不同的安全措施。例如,你可能为了防止密码被窃取,或者防止终端用户
受到“中间人”攻击,需要保证到达的是请求通过HTTPS的。或者,你要确保是一个真正的人而不是某种机器人或者自动进程在发送请求。这对于保护密码恢复
不受暴力破解攻击,或者防止他人很容易的复制你应用的关键内容。为了帮助你实现这些目标,Acegi Security完全支持自动“通道安全”("channel
security"),以及集成Jcaptcha来检测是否是真正人类用户。 <BR>Acegi
Security不仅提供了认证功能,而且提供了完备的授权功能。在授权方面主要有三个领域,授权web请求,授权方法调用,授权存取单个领域对象实例。
为了帮助你理解这些区别,对照考虑一下Servlet 规范中的web模式安全的授权功能,EJB容器管理安全以及文件系统安全。Acegi
Security提供了所有这些重要领域的完备功能,我们将在本手册的后面介绍。 <BR>1.2. 历史 <BR>Acegi
Security始于2003年晚期,当时在Spring
Developers邮件列表中有人提问是否有人考虑提供一个基于Spring的安全实现。当时,Srping的社区是相对比较小的(尤其是和今天相
比!),实际上Spring本身也是2003年早期才作为一个SourceForge项目出现的。对此问题的回应是它确实是一个值得研究的领域,虽然限于
时间无法进行深入。 <BR>有鉴于此,这个简单的安全实现虽然构建了但是并没有发布。几周以后,Spring社区的其他成员询问了安全框架,代码就被提供给了他们。
<BR>随后又有人请求,到了2004年一月,大约有20人左右在使用这些代码。另外一些人加入到这些先行的用户中来,并建议建立一个SourceForge项目,这个项目在2004年3月建立起来。
<BR>在 早期,该项目自身并布具备任何认证模块。认证过程依赖容器管理安全(Container Managed Security)而Acegi
Security注重授权。在一开始这样是合适的,但是随着越来越多的用户要求额外的容器支持,基于容器的认证的限制就显示出来了。另外一个相关的问题是
添加新的JAR文件到容器的classpath,通常会让最终用户感到困惑并且配置错误。 <BR>随后,Acegi
Security加入了认证服务。大约一年后,Acegi Security成为了一个Spring
Framework官方子项目。在2年半多的在多个软件项目中的活跃使用以及数以百计的改进和社区贡献,1.0.0最终版在2006年5月发布。
<BR>今天,Acegi
Security成为一个强大而活跃的社区。在支持论坛上有数以千计的帖子。14位开发人员专职开发,一个活跃的社区也定期共享补丁并支持他们的同侪。
<BR><BR>1.3. 发行版本号 <BR>理 解Acegi
Security的版本号是非常好处的,它可以帮助你判定升级的到新的版本是否需要花费很大精力。我们的正式发行版本使用Apache Portable Runtime
Project版本指引,可以在下述网站查看http://apr.apache.org/versioning.html。为了您查看方便,我们引用该
页的说明部分如下: <BR>“版本号由三个部分的整数组成:主版本号(MAJOR)、副版本号(MINOR)、补丁版本号(PATCH)。主要的含义
是主版本号(MAJOR)是不兼容的,API大规模升级。副版本号(MINOR)在源文件和可执行版和老版本保持兼容,补丁版本号(PATCH)则意味着
向前和向后的完全兼容”。 <BR>acegi参考手册(v1.0.4)[译]-第二章 技术概览[上] <BR><BR>第二章. 技术概览 <BR>2.1.
运行时环境 <BR>Acegi Security可以在JRE1.3中运行。这个发行版本中支持也Java
5.0,尽管对应的Java类型被分开打包到一个后缀是“tiger”的包中。因为Acegi
Security致力于以一种自包含的方式运行,因此不需要在JRE中放置任何特殊的配置文件。特别无需配置Java Authentication and
Authorization Service (JAAS)策略文件或者将Acegi Security放置到通用的classpath路径中。
<BR><BR>同样的,如果你使用EJB容器或者Servlet容器,同样无需放置任何特别的配置文件或者将Acegi
Security包含在服务器的类加载器(classloader)中。 <BR><BR>上述的设计提供了最大的部署灵活性,你可以直接把目标工件(JAR, WAR
或者 EAR))直接从一个系统copy到另一个系统,它马上就可以运行起来。 <BR><BR>2.2. 共享组件 <BR>让我们来看看Acegi
Security中最重要的一些共享组件。所谓共享组件是指在框架中处于核心地位,系统脱离了它们之后就不能运行。这些Java类型代表了系统中其他部分的构建单元,因此理解它们是非常重要的,即使你不需要直接和它们打交道。
<BR><BR>最 基础的对象是SecurityContextHolder。在这里存储了当前应用的安全上下文(security
context),包括正在使用应用程序的principal的详细信息。SecurityContextHolder默认使用ThreadLocal来
存储这些详细信息,这意味着即便安全上下文(security
context)没有被作为一个参数显式传入,它仍然是可用的。如果在当前principal的请求处理后清理线程,那么用这种方式使用
ThreadLocal是非常安全的。当然, Acegi Security自动为你处理这些,所以你无需担心。 <BR><BR>有些应用程序由于使
用线程的方式而并不是完全适用ThreadLocal。例如,Swing客户端可能需要一个Java Virtual
Machine中的所有线程都使用同样的安全上下文(security
context)。在这种情况下你要使用SecurityContextHolder.MODE_GLOBAL模式。另外一些应用程序可能需要安全线程产
生的线程拥有同样的安全标识符(security
identity)。这可以通过SecurityContextHolder.MODE_INHERITABLETHREADLOCAL来实现。你可以通
过两种方法来修改默认的SecurityContextHolder.MODE_THREADLOCAL。第一种是设置一个系统属性。或者,调用
SecurityContextHolder的一个静态方法。大部分的应用程序不需要修改默认值,不过如果你需要,那么请查看
SecurityContextHolder的JavaDocs获取更多信息。 <BR><BR>我们在SecurityContextHolder中
存储当前和应用程序交互的principal的详细信息。Acegi
Security使用一个Authentication对象来代表这个信息。尽管你通常不需要自行创建一个Authentication对象,用户还是经
常会查询Authentication对象。 <BR><BR>你可以在你的应用程序中的任何地方使用下述的代码块: <BR>java 代码 <BR><BR>1.
Object obj =
SecurityContextHolder.getContext().getAuthentication().getPrincipal(); <BR>2. if
(obj instanceof UserDetails) { <BR>3. String username =
((UserDetails)obj).getUsername(); <BR>4. } else { <BR>5. String username =
obj.toString(); <BR>6. } <BR><BR>上
述的代码展示了一些有趣的联系和关键的对象。首先,你会注意到在SecurityContextHolder和Authentication之间有一个媒
介对象。SecurityContextHolder.getContext() 方法实际上返回一个SecurityContext。Acegi
Security使用若干个不同的SecurityContext实现,以备我们需要存储一些和principal无关的特殊信息。一个很好的例子就是我
们的Jcaptcha集成,它需要知道一个需求是否是由人发起的。这样的判断和principal是否通过认证完全没有关系,因此我们将它保存在
SecurityContext中。 <BR><BR>从上述的代码片段可以看出的另一个问题是你可以从一个Authentication对象中获取一
个principal。Principal只是一个对象。通常可以把它cast为一个UserDetails对象。UserDetails在Acegi
Security中是一个核心接口,它以一种扩展以及应用相关的方式来展现一个principal。可以把UserDetails看作是你的用户数据库和 Acegi
Security在SecurityContextHolder所需要的东西之间的一个适配器(adapter)。作为你自己用户数据库的一个展现,你可
能经常要把它cast到你应用程序提供的原始对象,这样你就可以调用业务相关的方法(例如 getEmail(), getEmployeeNumber())。
<BR><BR>现在你可能已经开始疑惑,那我什么时候提供UserDetails对象呢?我要如何提供呢? <BR>我
想你告诉过我这个东西是声明式的,我不需要写任何Java代码-那怎么做到呢?对此的简短回答就是有一个叫做UserDetailsService的特殊
接口。这个接口只有一个方法,接受一个Sring类型的参数并返回一个UserDetails。Acegi
Security提供的大多数认证提供器将部分认证过程委派给UserDetailsService。UserDetailsService用来构建保存
在SecurityContextHolder中的Authentication对象。好消息是我们提供若干个UserDetailsService的实
现,包括一个使用in-memory map和另一个使用JDBC的。 <BR>大多数用户还是倾向于写自己的实现,这样的实现经常就是简单的构建于已 有的Data
Access Object
(DAO)上,这些DAO展现了他们的雇员、客户、或者其他企业应用程序中的用户。要记得这样做的好处,不论你的UserDetailsService返
回什么,它总是可以从SecurityContextHolder中获取,象上面的代码显示的那样。 <BR><BR>除了principal,
Authentication提供的另一个重要方法就是getAuthorities()。这个方法返回一个GrantedAuthority对象数组。
GrantedAuthority,毫无疑问,就是授予principal的权限。这些权限通常是“角色”,例如ROLE_ADMINISTRATOR
或者ROLE_HR_SUPERVISOR。这些角色稍后配置到web授权,方法授权和领域对象授权。Acegi
Security的其他部分能够处理这些权限,并且期待他们被提供。通常你会从UserDetailsService中返回 GrantedAuthority对象。
<BR><BR>通常GrantedAuthority对象都是应用范围的权限。它们都不对应特定的领域对
象。因此,你应该不会有一个代表54号员工对象的GrantedAuthority,因为这样会有数以千计的authority,你马上就会用光所有内存
(或者,至少会让系统花太长时间来认证一个用户)。当然,Acegi Security会高效的处理这种普遍的需求,但是你不会使用领域对象安全功能来实现这个目的。
<BR><BR>最后,但不是不重要,你有时候需要在 HTTP
请求之间存储SecurityContext。另外有些时候你在每次请求的时候都会重新认证principal,不过大部分时候你会存储
SecurityContext。HttpSessionContextIntegrationFilter在HTTP之间存储
SecurityContext。正如类名字显示的那样,它使用HttpSession来进行存储。基于安全原因,你永远都不要直接和
HttpSession交互。没有理由这么做,所以记得使用SecurityContextHolder来代替。 <BR><BR>让我们回忆一下,Acegi
Security的基本组成构件是: <BR>&S226;
SecurityContextHolder,提供对SecurityContext的所有访问方式。 <BR>&S226; SecurityContext,
存储Authentication以及可能的请求相关的安全信息。 <BR>&S226;
HttpSessionContextIntegrationFilter, 在web请求之间把SecurityContext存储在HttpSession中。
<BR>&S226; Authentication, 以Acegi Security的方式表现principal。 <BR>&S226;
GrantedAuthority, 表示赋予一个principal的应用范围的权限。 <BR>&S226; UserDetails,
为从你的应用程序DAO中获取必要的信息来构建一个Authentication 对象。 <BR>&S226;
UserDetailsService,用传入的String类型的username(或者认证ID,或类似)来创建一个UserDetails。
<BR><BR>现在你已经理解了这些重复使用的组件,让我们仔细看看认证过程吧。 <BR><BR>2.3. 认证 <BR>正
如我们在手册开始部分所说的那样,Acegi Security适用于很多认证环境。虽然我们建议大家使用Acegi
Security自身的认证功能而不是和容器管理认证(Container Managed
Authentication)集成,但是我们仍然支持这种和你私有的认证系统集成的认证。让我们先从Acegi
Security完全自行管理管理web安全的角度来探究一下认证,这也是最复杂和最通用的情形。 <BR><BR>想象一个典型的web应用的认证过程:
<BR><BR>1.你访问首页,点击一个链接。 <BR>2.一个请求被发送到服务器,服务器判断你是否请求一个被保护的资源。
<BR>3.因为你当前未被认证,服务器发回一个回应,表明你必须通过认证。这个回应可能是一个HTTP回应代码,或者重定向到一个特定的网页。
<BR>4.基于不同的认证机制,你的浏览器会重定向到一个网页好让你填写表单,或者浏览器会用某种方式获取你的身份认证(例如一个BASIC认证对话框,一个cookie,一个X509证书等等。)。
<BR>5.浏览器会发回给服务器一个回应。可能是一个包含了你填写的表单内容的HTTP POST,或者一个包含你认证详细信息的HTTP header。
<BR>6.接下来服务器会判断提供的认证信息是否有效。如果它们有效,你进入到下一步。如果它们无效,那么通常请求你的浏览器重试一次(你会回到上两步)。
<BR>7.你引发认证的那个请求会被重试。但愿你认证后有足够的权限访问那些被保护的资源。如果你有足够的访问权限,请求就会成功。否则,你将会受到一个意味“禁止”的HTTP403错误代码。
<BR><BR>在Acegi
Security中,对应上述的步骤,有对应的类。主要的参与者(按照被使用的顺序)是:ExceptionTranslationFilter,
AuthenticationEntryPoint, 认证机制(authentication mechanism),
以及AuthenticationProvider。 <BR><BR>ExceptionTranslationFilter是Acegi
Security用来检测任何抛出的安全异常的过滤器(filter)。这种异常通常是由AbstractSecurityInterceptor抛出
的,它是授权服务的主要提供者。我们将会在下一部分讨论AbstractSecurityInterceptor,现在我们只需要知道它产生Java异
常,并且对于HTTP或者如何认证一个principal一无所知。反而是ExceptionTranslationFilter提供这样的服务,它负责
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -