一、
CAS
简介
1.1
CAS
是什么
CAS (Central Authentication Service) 是 Yale 大学发起的一个 Java 开源项目,旨在为 Web 应用系统提供一种可靠的 单点登录 解决方案( Web SSO ), CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。 CAS 具有以下特点: 1、 开源的企业级单点登录解决方案; 2、 CAS Server 为需要独立部署的 Web 应用; 3、 CAS Client 支持非常多的客户端 ( 指单点登录系统中的各个 Web 应用 ) ,包括 Java, .Net, PHP, Perl, 等。
1.2
CAS
原理
从结构上看,
CAS
包含两个部分:
CAS Server
和
CAS Client
。
CAS Server
需要独立部署,主要负责对用户的认证工作,
它会处理用户名
/
密码等凭证
(Credentials)
;
CAS Client 部署在客户端, 负责处理 对本地 Web 应用(客户端)受保护资源的访问请求,并且当需要对请求方进行身份认证时,重定向到 CAS Server 进行认证, 下图是 CAS 最基础协议:
1
、
CAS Client
与受保护的客户端应用部署在一起,以
Filter
方式保护受保护的资源。对于访问受保护资源的每个
Web
请求,
CAS Client
会分析该请求的
Http
请求中是否包含
Service Ticket
(
ST
)和
Ticket Granting tieckt(TGT)
(??),如果没有,则说明当前用户尚未登录,于是将请求重定向到指定好的
CAS Server
登录地址,并传递
Service
(也就是要访问的目的资源地址),以便登录成功过后转回该地址。用户在第
3
步中输入认证信息,如果登录成功,
CAS Server
随机产生一个相当长度、唯一、不可伪造的
Service Ticket
,并缓存以待将来验证,之后系统自动重定向到
Service
所在地址,并为客户端浏览器设置一个
Ticket Granted Cookie
(
TGC
),
CAS Client
在拿到
Service
和新产生的
Ticket
过后,在第
5
,
6
步中与
CAS Server
进行身份核实,以确保
Service Ticket
的合法性。
2
、在该协议中,所有与
CAS
的交互均采用
SSL
协议确保
ST
和
TGC
的安全性。协议工作过程中会有
2
次重定向的过程,但是
CAS Client
与
CAS Server
之间进行
Ticket
验证的过程对于用户是透明的。
3
、
CAS
如何实现
SSO
当用户访问另一服务再次被重定向到
CAS Server
的时候,
CAS Server
会主动获到这个
TGC cookie
,然后做下面的事情:
1)
如果
User
的持有
TGC
且其还没失效,那么就走基础协议图的
Step4
,达到了
SSO
的效果;
2)
如果
TGC
失效,那么用户还是要重新认证
(
走基础协议图的
Step3)
。
1.3
CAS
相关词汇及概念
TGC(ticket-granting cookie)--
-------
授权的票据证明,由
CAS Server
通过
SSL
方式发送给终端用户;
KDC( Key Distribution Center ) ----------
密钥发放中心;
ST (Service ticket)
---------
服务票据,
由
KDC
的
TGS
发放,
ST
只能被尝试验证一次
。
任何一台
Workstation
都需要拥有一张有效的
Service Ticket
才能访问域内部的应用
(Applications)
。
如果能正确接收
Service Ticket
,说明在
CASClient-CASServer
之间的信任关系已经被正确建立起来,通常为一张数字加密的证书;
Ticket Granting tieckt(TGT) ---------
票据授权票据,由
KDC
的
AS
发放。即获取这样一张票据后,以后申请各种其他服务票据
(ST)
便不必再向
KDC
提交
Credentials
(凭证或身份认证信息
)
;
Authentication Service (AS) ---------
认证服务,索取
Crendential
,发放
TGT
;
Ticket-Granting Service (TGS) ---------
票据授权服务,索取
TGT
,发放
ST
。
1.4
CAS
安全性
CAS
的安全性从
v1
到
v3
,都很依赖于
SSL
,它假定了这样一个事实,用户在一个非常不安全的网络环境中使用
SSO
,
Hacker
的
Sniffer
会很容易抓住所有的
Http Traffic
,包括通过
Http
传送的密码甚至
Ticket
票据。
1、
TGC
安全性
对于一个
CAS
用户来说,最重要是要保护它的
TGC
,如果
TGC
不慎被
CAS Server
以外的实体获得,
Hacker
能够找到该
TGC
,然后冒充
CAS
用户访问所有授权资源。
TGC
是
CAS Server
通过
SSL
方式发送给终端用户,因此,要截取
TGC
难度非常大,从而确保
CAS
的安全性。但
CAS
的传输安全性仅仅依赖于
SSL
。
TGC
面临的风险
主要并非传输窃取,而是存活周期内(
logout
前)被使用(如:离开了电脑)或窃取。
TGC
有自己的存活周期。可以在
web.xml
中,通过
grantingTimeout
来设置
CAS TGC
存活周期的参数,参数默认是
120
分钟,在合适的范围内设置最小值,太短,会影响
SSO
体验,太长,会增加安全性风险。
2、
ST
安全性
ST
(
Service Ticket
)是通过
Http
传送的,网络中的其他人可以
Sniffer
到其他人的
Ticket
。
CAS
协议从几个方面让
Service Ticket
变得更加安全:
1)
ST
只能使用一次:
CAS
协议规定,无论
ST
验证是否成功,
CAS Server
都会将服务端的缓存中清除该
Ticket
,从而可以确保一个
Service Ticket
不被使用两次;
2)
ST
在一段时间内失效:假设用户拿到
ST
之后,他请求服务的过程又被中断了,
ST
就被空置了,事实上,此时
TS
仍然有效。
CAS
规定
Service Ticket
只能存活一定的时间,然后
CAS Server
会让它失效。可通过在
web.xml
中配置参数,让
ST
在多少秒内失效。
3)
ST
是基于随机数生成的。
二、
Spring Security
简介
2.1 Spring Security
是什么
Spring Security
开始于
2003
年底,那时候叫
“spring
的
Acegi
安全系统
”
。
Acegi
在
2007
年底,正式成为
spring
组合项目,被更名为
“Spring Security”
。
Spring Security
基于
Spring
框架,提供了一套
Web
应用安全性的完整解决方案。一般来说,
Web
应用的安全性包括用户认证(
Authentication
)和用户授权(
Authorization
)两个部分。
用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。
用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。
对于上面提到的两种应用情景,
Spring Security
框架都有很好的支持。在用户认证方面,
Spring Security
框架支持主流的认证方式,包括
HTTP
基本认证、
HTTP
表单验证、
HTTP
摘要认证、
OpenID
和
LDAP
等。在用户授权方面,
Spring Security
提供了
基于角色
的访问控制和访问控制列表(
Access Control List
,
ACL
),可以对应用中的领域对象进行细粒度的控制。
2.3
如何控制权限
1、
概要
Spring
使用由
Filter
组成的
Chain
,来判断权限。
Spring
预定义了很多
out-of-boxed filter
供开发者直接使用。每个
Filter
一般情况下(有些
Filter
是
abstract
的)都和配置文件的一个元素(有的情况下可能是属性)对应。比如:
AUTHENTICATION_PROCESSING_FILTER
,对应配置文件里面的:
http/form-login
元素。
如果
Spring
提供的
Filter
不能满足系统的权限功能,开发者可以自定义
Filter
,然后把
Filter
放在某个
Filter Chain
的某个位置。可以替换掉原有
Filter Chain
的某个
Filter
,也可以放在某个
Filter
之前或者之后。
总之,
Spring Security
采用
Filter Chain
模式判断权限,
Spring
提供了一些
Filter
,也支持开发者自定义
Filter
。
2、
控制内容
Spring Security 提供对 URL 、 Bean Method 、 Http Session 、领域对象这四种内容的控制,分别如下: 1) URL 可以分为需要权限判断的 url ,不需要权限判断的 url ,登录表单 url 。需要权限判断的 url ,仅限于做角色判断,就是说判断当前用户是否具有指定的角色。 2) Bean Method Spring 支持对 Service layer method 做权限判断。也仅限于做角色判断。配置方式有 2 种: Annotation : 写在 Java 源代码里面( Annotation ),如: @Secured("ROLE_TELLER") (该方法只有具有 TELLER 角色的用户能够访问,否则抛出异常); 写在配置文件里面,如: <protect method="set*" access="ROLE_ADMIN" /> (该 bean 的所有 set 方法,只有具有 ADMIN 角色的用户能够访问,否则抛出异常)。 3) Http Session 控制一个用户名是否能重复登录,以及重复登录次数,并非重试密码次数。 4) 领域对象(待完善)
复杂程序常常需要定义访问权限,不是简单的
web
请求或方法调用级别。而是,安全决议,需要包括谁(认证),哪里(
MethodInvocation
)和什么(一些领域对象)。换而言之,验证决议也需要考虑真实的领域对象实例,方法调用的主体。主要通过
ACL
(访问控制列表)实现。
2.4
权限控制的几种配置方法
在
Spring Security 3
的使用中,权限控制有
4
种配置方法:
1、
全部利用配置文件,将用户、权限、资源
(url)
硬编码在
xml
文件中;
2、
用户和权限用数据库存储,而资源
(url)
和权限的对应采用硬编码配置;
3、
细分角色和权限,并将用户、角色、权限和资源均采用数据库存储,并且自定义过滤器,代替原有的
FilterSecurityInterceptor
过滤器,并分别实现
AccessDecisionManager
、
InvocationSecurityMetadataSourceService
和
UserDetailsService
,并在配置文件中进行相应配置;(将主要考虑该方法)
4、
修改
spring security
的源代码,主要是修改
InvocationSecurityMetadataSourceService
和
UserDetailsService
两个类。
前者是将配置文件或数据库中存储的资源
(url)
提取出来加工成为
url
和权限列表的
Map
供
Security
使用,后者提取用户名和权限组成一个完整的
(UserDetails)User
对象,该对象可以提供用户的详细信息供
AuthentationManager
进行认证与授权使用。比较暴力,不推荐。
2.5
主要内置对象或内容
1、
Spring Security
默认的过滤器顺序列表
2、
2.5
主要应用模式
1、
自定义授权管理
自定义
Filter
以及相关辅助类,实现用户、角色、权限、资源的数据库管理,涉及相关接口或类说明如下:
1)
AbstractSecurityInterceptor
具体实现类作为过滤器,该过滤器要插入到授权之前。在执行
doFilter
之前,进行权限的检查,而具体的实现交给
accessDecisionManager
。
2)
FilterInvocationSecurityMetadataSource
具体实现类在初始化时,要实现从数据库或其它存储库中加载所有资源与权限(角色),并装配到
MAP <String, Collection<ConfigAttribute>>
中。 资源通常为
url
, 权限就是那些以
ROLE_
为前缀的角色,资源为
key
, 权限为
value
。 一个资源可以由多个权限来访问。
3)
UserDetailService
具体实现类从存储库中读取特定用户的各种信息(用户的密码,角色信息,是否锁定,账号是否过期等)。唯一要实现的方法:
public UserDetails loadUserByUsername(String username)
4)
AccessDecisionManager
匹配权限以决定是否放行。主要实现方法:
public
void
decide
(Authentication authentication, Object object,
Collection<ConfigAttribute> configAttributes)
//In this method, need to compare authentication with configAttributes.
A object is a URL, a filter was find permission configuration by this URL, and pass to here.
Check authentication has attribute in permission configuration (configAttributes)
If not match corresponding authentication, throw a AccessDeniedException.
2.6 Spring Security
评价
在
Spring Security
世界里,可以区分出哪些资源可以匿名访问,哪些需要角色权限,哪个页面提供登录功能;怎样进行用户身份认证,用户的密码如何加密。哪些资源必须使用
https
协议,资源和访问端口有怎样的对应关系。
下面就优点和缺点对
Spring Security
进行点评。
1、
优点
总体说来
Spring Security
具有以下几个优点:
1)
提供了一套权限框架,这套框架是可行的;
2)
提供了很多用户身份认证功能,可以节约大量开发工作;
3)
提供了角色判断功能,这点既是优点又是缺点;
4)
提供了
form-login
、
remember me
等控制。
其中
2
、
4
两点,对于我们中国开发者,可用性并不大。我们的系统大多采用用户名
/
密码身份认证模式,大多公司都有可复用代码。
form-login
、
remember me
等这些功能,并不是难以开发,而且可用之处也并不多。
2、
缺点
Spring Security
存在以下几个硬伤:
1)
角色被“编码”到配置文件和源文件,这样最终用户就不能创建角色了。但最终用户期望自己来控制角色。因为在项目实施过程中,客户可能并不能确定有哪些角色,以及角色怎么分配给系统用户。角色大多需要等到系统上线后,才能确定。这些编码有:
a)
url
的权限控制,
<intercept-url pattern="/**" access="ROLE_USER" />
;
b)
java
方法的权限控制,
@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
;
c)
java
方法的权限控制,
<protect method="set*" access="ROLE_ADMIN" />
;
2)
RBCA
这种被广泛运用的模型,没有在
Spring Security
体现出来;
3)
Spring Security
没有提供好的细粒度(数据级)权限方案,提供的缺省实现维护工作量大,在大数据量情况下,几乎不可用;
4)
Spring Security
对于用户、角色、权限之间的关系,没有提供任何一种维护界面。不过从
Spring Security
角度看,确实没有必要有界面。角色创建、角色和权限直接的关系,都被“编码”到配置文件和源文件了;
5)
Spring Security
学习难度大,配置文件还是很多。
三、
CAS Server
与
LDAP
整合
CAS Server
与
LDAP
整合,主要是使用
LDAP
来进行统一认证。
3.1
环境需求
1
、
CAS
服务包:
cas-server-3.3.5-release
2
、
LDAP
:
apacheds-1.5.7-setup
(
LDAP
)
3
、
Tomcat
:
tomcat-6.0.18
4
、
JDK
:
jdk1.5+
3.1
搭建
CAS Server
1、 生成服务器证书(以下方式包含了双向认证)
部署
CAS3
服务器端所需得
ssl
环境生成
,
预备生成文件
: cacerts server.keystore client.keystore
,
server.cer client.cer
1
)生成服务器端库文件
(
生成的时候,
第一项
name
一定要为完整计算机名称或域名
)
2
)导出服务器端证书
5
)导入服务器端证书
将如上生成的
cacerts
,
server.keystore
,
client.keystore
,
server.cer
,
client.cer
文件
分别拷贝到
cas
服务器以及应用客户端(
server.cer
)
TOMCAT_HOME
主目录以及
JAVA_HOEM/jre/lib/security
文件下
(
每个子系统的
tomcat
也要拷贝进去
)
。
2、 部署 CAS Server 1) 将下载后的 cas-server-3.3.5-release.zip 解压后,进入 cas-server-3.3.5\modules 目录,将 cas-server-webapp-3.3.5.war 重命名为: cas.war 并将它拷贝到 %TOMCAT_HOME%/webapps/ 下; 2) 启动 tomcat 后,停止 tomcat, 然后看到有一个 cas 目录,有的话把 cas.war 删除掉; 3) 修改 TOMCAT 配置文件: tomcat/conf/server.xml 放开注释改成如下内容 : <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="E:\servers\tomcat-6.0.18-casServer\server.keystore" keystorePass="changeit" /> 注意:证书的路径和密码需做对应修改。 4) 启动 TOMCAT 在 IE 地址栏输入: https://localhost(IP):8443/cas ,如显示如下图,表明成功:
5)
3.2 LDAP
服务安装
见附件“ LDAP 服务安装说明 .doc ”。
3.3
配置
CAS Server
与
LDAP
1 、 修改 webapps\cas\WEB-INF\deployerConfigContext.xml 文件 具体文件配置:注释用” <!-- --> ” <!— 注释掉下面这行 , 该行主要实现使用用户和密码一致的值便可登录,如下: --> <!--bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" /--> 2 、在刚才注释的那个位置下面输入: <bean class="org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler"> <property name="filter" value=" cn=%u " /> <property name="searchBase" value=" ou=Users,ou=System " /> <property name="contextSource" ref=" apchedsContextSource " /> </bean> 该段内容主要是加入 LDAP 的过滤条件及访问目录。 3 、在配置文件的倒数第 2 行,加入如下代码配置 ( 主要为需要访问的 LDAP 服务地址及用户名、密码 ) : <bean id="apchedsContextSource" class="org.springframework.ldap.core.support.LdapContextSource"> <property name="userDn" value=" uid=admin,ou=system " /> <property name="password" value=" 123456 " /> <property name="pooled" value="false" /> <property name="urls"> <list> <value>ldap://localhost:10389/</value> </list> </property> <property name="baseEnvironmentProperties"> <map> <entry> <key> <value>java.naming.security.authentication</value> </key> <value>simple</value> </entry> </map> </property> </bean>
3.4
验证
CAS Server
与
LDAP
在
IE
地址栏输入
“
https://localhost:8443/cas
“
,
并用
LDAP
建立的用户名及密码登录,正常情况如下图所示:
四、
CAS Client
与
Spring Security
整合
4.1
环境需求
1
、
CAS Client
:
cas-client-core-3.2.1.jar
放入
Web
应用的
lib
中
2
、
Spring Security
:
spring-security-cas-client-3.0.2.RELEASE.jar
,在基于
spring security
项目中加入
cas
相应的依赖
jar
包
4.2
搭建
CAS Client
(即
Spring Security
应用)
1、
导入服务端生成证书
复制
cas
服务端生成证书
server.cer
到客户端(
TOMCAT_Home
下),并将证书导入
JDK
中
,
keytool -import -trustcacerts -alias casserver -file server.cer -keystore D:\Java\jre1.6.0_02\lib\security\cacerts -storepass changeit
注此处的
jre
必须为
JDK
路径下的
jre
。
2、
配置
CAS Client
应用的
web.xml
增加如下:
<!-- spring
配置文件
-->
<
context-param
>
<
param-name
>
contextConfigLocation
</
param-name
>
<
param-value
>
classpath:applicationContext.xml,classpath:applicationContext-security.xml
</
param-value
>
</
context-param
>
<!-- Character Encoding filter -->
<
filter
>
<
filter-name
>
encodingFilter
</
filter-name
>
<
filter-class
>
org.springframework.web.filter.CharacterEncodingFilter
</
filter-class
>
<
init-param
>
<
param-name
>
encoding
</
param-name
>
<
param-value
>
UTF-8
</
param-value
>
</
init-param
>
</
filter
>
<
filter-mapping
>
<
filter-name
>
encodingFilter
</
filter-name
>
<
url-pattern
>
/*
</
url-pattern
>
</
filter-mapping
>
<!-- spring security filter -->
<!--
DelegatingFilterProxy
是一个
SpringFramework
的类,它可以代理一个
applicationcontext
中定义的
Springbean
所实现的
filter -->
<
filter
>
<
filter-name
>
springSecurityFilterChain
</
filter-name
>
<
filter-class
>
org.springframework.web.filter.DelegatingFilterProxy
</
filter-class
>
</
filter
>
<
filter-mapping
>
<
filter-name
>
springSecurityFilterChain
</
filter-name
>
<
url-pattern
>
/*
</
url-pattern
>
</
filter-mapping
>
<!-- spring
默认侦听器
-->
<
listener
>
<
listener-class
>
org.springframework.web.context.ContextLoaderListener
</
listener-class
>
</
listener
>
3、
配置
applicationContext-security-ns.xml
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
beans:beans
xmlns
=
"http://www./schema/security"
xmlns:beans
=
"http://www./schema/beans"
xmlns:xsi
=
"http://www./2001/XMLSchema-instance"
xsi:schemaLocation
=
"http://www./schema/beans
http://www./schema/beans/spring-beans-3.0.xsd
http://www./schema/security
http://www./schema/security/spring-security-3.0.xsd"
>
<!--
设置相应的切入点与
filter,auto-config="false"
不使用
http
的自动配置
-->
<
http
auto-config
=
"false"
entry-point-ref
=
"casAuthenticationEntryPoint"
access-denied-page
=
"/common/403.jsp"
>
<
intercept-url
pattern
=
"/jsp/forbidden/**"
access
=
"ROLE_USER"
></
intercept-url
>
<
intercept-url
pattern
=
"/**"
filters
=
"none"
></
intercept-url
>
<
custom-filter
position
=
"CAS_FILTER"
ref
=
"casAuthenticationFilter"
/>
<!-- custom-filter before="LOGOUT_FILTER" ref="requestSingleLogoutFilter" /> -->
<!-- custom-filter before="CAS_FILTER" ref="singleLogoutFilter" /> -->
</
http
>
<!-- global-method-security
只能定义一个
-->
<!--
启用基于安全的注解
-->
<
global-method-security
secured-annotations
=
"enabled"
jsr250-annotations
=
"enabled"
>
<
protect-pointcut
=
"execution(* com.coin.acs.demo.bo.*Service.*(..))"
access
=
"ROLE_USER"
/>
<
protect-pointcut
=
"execution(* com.coin.acs.demo.bo.*AOP.update*(..))"
access
=
"ROLE_USER"
/>
</
global-method-security
>
<
beans:bean
id
=
"casAuthenticationEntryPoint"
class
=
"org.springframework.security.cas.web.CasAuthenticationEntryPoint"
>
<
beans:property
name
=
"loginUrl"
value
=
"https://localhost:8443/cas/login"
/>
<!-- SSO
登录地址
-->
<
beans:property
name
=
"serviceProperties"
ref
=
"serviceProperties"
/>
</
beans:bean
>
<!-- serviceProperties
为认证成功后服务端返回的地址
.
该地址将作为参数传递到服务端
,
此处不能写为
IP
的形式。需写为主机名
(
证书生成时写的计算机全名
)
或域名
-->
<
beans:bean
id
=
"serviceProperties"
class
=
"org.springframework.security.cas.ServiceProperties"
>
<
beans:property
name
=
"service"
value
=
"http://localhost:9001/client/j_spring_cas_security_check"
/>
<!-- sendRenew
为
boolean
类型
当为
true
时每新打开窗口则需重新登录
-->
<
beans:property
name
=
"sendRenew"
value
=
"false"
/>
</
beans:bean
>
<!--
在认证管理器中注册
cas
认证提供器
-->
<
authentication-manager
alias
=
"authenticationManager"
>
<
authentication-provider
ref
=
"casAuthenticationProvider"
/>
</
authentication-manager
>
<!-- cas
认证过滤器
-->
<
beans:bean
id
=
"casAuthenticationFilter"
class
=
"org.springframework.security.cas.web.CasAuthenticationFilter"
>
<
beans:property
name
=
"authenticationManager"
ref
=
"authenticationManager"
/>
</
beans:bean
>
<!-- cas
认证提供器,定义客户端的验证方式
-->
<
beans:bean
id
=
"casAuthenticationProvider"
class
=
"org.springframework.security.cas.authentication.CasAuthenticationProvider"
>
<
beans:property
name
=
"authenticationUserDetailsService"
ref
=
"authenticationUserDetailsService"
/>
<!--
客户端只验证用户名是否合法
-->
<
beans:property
name
=
"serviceProperties"
ref
=
"serviceProperties"
/>
<
beans:property
name
=
"ticketValidator"
>
<
beans:bean
class
=
"org.jasig.cas.client.validation.Cas20ServiceTicketValidator"
>
<
beans:constructor-arg
index
=
"0"
value
=
"https://localhost:8443/cas"
/>
</
beans:bean
>
</
beans:property
>
<
beans:property
name
=
"key"
value
=
"cas"
/>
</
beans:bean
>
<!-- authorities
对应
CAS server
的
登录属性,
在此设置到
spirng security
中,用于
spring security
的验证
-->
<
beans:bean
id
=
"authenticationUserDetailsService"
class
=
"org.springframework.security.cas.userdetails.GrantedAuthorityFromAssertionAttributesUserDetailsService"
>
<
beans:constructor-arg
>
<
beans:array
>
<
beans:value
>
authorities
</
beans:value
>
</
beans:array
>
</
beans:constructor-arg
>
</
beans:bean
>
</
beans:beans
>
配置完毕。
五、
参考资料
1、
Spring Security-3.0.1
中文官方文档
2、
http://metadmin./blog/364132
“
Spring Security
优劣之我见”
3、
http://dead-knight./blog/1520080
|
|
来自: ebonyzhang > 《待分类》