使用Spring Security3的四种方法概述
那么在Spring Security3的使用中,有4种方法:
一种是全部利用配置文件,将用户、权限、资源(url)硬编码在xml文件中,已经实现过,并经过验证;
二种是用户和权限用数据库存储,而资源(url)和权限的对应采用硬编码配置,目前这种方式已经实现,并经过验证。
三种是细分角色和权限,并将用户、角色、权限和资源均采用数据库存储,并且自定义过滤器,代替原有的FilterSecurityInterceptor过滤器,
并分别实现AccessDecisionManager、InvocationSecurityMetadataSourceService和UserDetailsService,并在配置文件中进行相应配置。
目前这种方式已经实现,并经过验证。
四是修改spring security的源代码,主要是修改InvocationSecurityMetadataSourceService和UserDetailsService两个类。
前者是将配置文件或数据库中存储的资源(url)提取出来加工成为url和权限列表的Map供Security使用,后者提取用户名和权限组成一个完整的 (UserDetails)User对象,该对象可以提供用户的详细信息供AuthentationManager进行认证与授权使用。
该方法理论上可行,但是比较暴力,也没有时间实现,未验证,以后再研究。
说明一下,我目前调通的环境为: java1.6 + struts2.1.6 + spring3.0.1 + hibernate3.3.1 + spring security3.0.2 + oracle9i + weblogic10.3,
顺便提一下,目前(2011-4-2)serutity的最新版本为3.1,比较稳定的版本为3.0.5和2.0.6。
当然在进行spring security3的下面4种方法介绍之前,先假定SSH2的环境已经配置完毕,进入正常开发的过程,并且已经导入
spring security3.0.2的5个jar包,分别为:
spring-security-acl-3.0.2.RELEASE.jar
spring-security-config-3.0.2.RELEASE.jar
spring-security-core-3.0.2.RELEASE.jar
spring-security-taglibs-3.0.2.RELEASE.jar
spring-security-web-3.0.2.RELEASE.jar
当然还有其他相关的jar包,在此不再赘述。
第一种方法
第一种方法比较简单,可参考Spring Security自带的例子spring-security-samples-tutorial-3.0.2.RELEASE。
这里给出下载网址:http://www.springsource.com/download/community?sid=1087087,不过在下载之前必须填写相应的用户信息,才允许下载。各种版本号的均可以下载。
在spring-security-samples-tutorial-3.0.2.RELEASE的例子里,硬编码的配置请参见applicationContext-security.xml文件中的内容。
里面配置了用户名、经过MD5加密后的密码密文、相关的权限,以及与权相对应的访问资源(URL)。还有对于Session超时时的处理。
特别是因为版本号为3.0.2,因此还增加了对表达式的配置演示,具体内容请参见该例子。
当然你最好运行起该例子来,感受一下,你可以直接将下载下来的解压缩后的文件夹中找到spring-security-samples- tutorial-3.0.2.RELEASE.war文件,然后拷贝到Tomcat的安装目录下的\webapps文件夹下,然后运行Tomcat的服务器,服务器在启动过程中,会自动解开该war文件,在IE内输入http://localhost:8080/webapps/spring-security-samples-tutorial-3.0.2.RELEASE 就可以运行该系统了。在此不再赘述。
第二种方法
第二种方法的代码如下:
使用到的两个表,用户表和权限表的SQL语句。将用户和权限以数据库进行存储。
create
table
USERS(
USERNAME
VARCHAR2
(
50
)
not
null
,
PASSWORD
VARCHAR2
(
50
)
not
null
,
ENABLED
NUMBER
(
1
)
not
null
,
USERNAMECN
VARCHAR2
(
50
),
primary
key
( username )
)
create
table
AUTHORITIES(
USERNAME
VARCHAR2
(
50
)
not
null
,
AUTHORITY
VARCHAR2
(
50
)
not
null
)
-- 外键使用户和权限相联。
Create
/
Recreate
primary
,
unique
and
foreign
key
constraints
alter
table
AUTHORITIES
add
constraint
FK_AUTHORITIES_USERS
foreign
key
(USERNAME)
references
USERS (USERNAME);
可插入几条数据做为试验,首先插入用户:
insert
into
users (USERNAME, PASSWORD, ENABLED, USERNAMECN, ROWID)
values
(
'
lxb
'
,
'
c7d3f4c857bc8c145d6e5d40c1bf23d9
'
,
1
,
'
登录用户
'
,
'
AAAHmhAALAAAAAOAAA
'
);
insert
into
users (USERNAME, PASSWORD, ENABLED, USERNAMECN, ROWID)
values
(
'
admin
'
,
'
ceb4f32325eda6142bd65215f4c0f371
'
,
1
,
'
系统管理员
'
,
'
AAAHmhAALAAAAAPAAA
'
);
insert
into
users (USERNAME, PASSWORD, ENABLED, USERNAMECN, ROWID)
values
(
'
user
'
,
'
47a733d60998c719cf3526ae7d106d13
'
,
1
,
'
普通用户
'
,
'
AAAHmhAALAAAAAPAAB
'
);
再插入角色:
insert into authorities (USERNAME, AUTHORITY, ROWID)
values ('admin', 'ROLE_PLATFORMADMIN', 'AAAHmjAALAAAAAgAAA');
insert into authorities (USERNAME, AUTHORITY, ROWID)
values ('admin', 'ROLE_SYSADMIN', 'AAAHmjAALAAAAAgAAB');
insert into authorities (USERNAME, AUTHORITY, ROWID)
values ('lxb', 'ROLE_LOGIN', 'AAAHmjAALAAAAAeAAA');
insert into authorities (USERNAME, AUTHORITY, ROWID)
values ('lxb', 'ROLE_LOGINTOWELCOME', 'AAAHmjAALAAAAAeAAB');
insert into authorities (USERNAME, AUTHORITY, ROWID)
values ('user', 'ROLE_USER', 'AAAHmjAALAAAAAgAAC');
第二种方法之密码加密
可能要有人要问,用户表里面的密码是如何取得的呢?这个密码是通过MD5进行加密过的,并且以用户名做为了盐值,最后就成为32位数字这个样子,这个你可以参见下面applicationContext-Security.xml中的password-encoder和salt- source的配置就会明白。
那么在spring security3中是如何加密的呢?当我们设置了pawwrod-encoder和salt-source之后,Spring Security3会根据配置,采用相匹配的加密算法(比如设置了MD5加密算法)再加上salt-source进行加密,形成32位数字的密文。
比如用户名为yew,密码为yew1234,盐值为用户名yew。那么最后加密的明文为“yew1234{yew}”,密文就为“8fe2657d1599dba8e78a7a0bda8651bb”。
我们在试验过程中,通常喜欢先将几个常用的用户及密码插入数据库进行试验,这种情况下如何得到该用户的密码密文呢?
不妨试试我这个办法,假设,用户名为user,密码明文为user369,而且在配置文件里面设置了以MD5作为加密算法,并以用户名做为盐值。
那么你可以首先将各个信息组合成待加密的密码明文, 应是 密码明文 + { + 盐值 + }, 那么很明显,上述user的密码明文应当是:
user369{user}
拿上述的字串拷贝到 http://www.51240.com/md5jiami/ 网页上的输入框里,点击加密按钮,下面即可生成32位数字的密码密文。
哈哈,屡试不爽啊。这个方法要谨慎使用,一般人我不告诉他。
第二种方法之相关配置
将权限及资源(URL或Action)的关系配置在xml文件中,并且配置与Spring Security3相关的其他配置:
1、applicationContext-Security.xml代码:
<
b:beans
xmlns
="http://www.springframework.org/schema/security"
xmlns:b
="http://www.springframework.org/schema/beans"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd"
>

<
http
auto-config
="true"
access-denied-page
="/accessDenied.jsp"
>
<!--
不要过滤图片等静态资源,其中**代表可以跨越目录,*不可以跨越目录。
-->
<
intercept-url
pattern
="/**/*.jpg"
filters
="none"
/>
<
intercept-url
pattern
="/**/*.png"
filters
="none"
/>
<
intercept-url
pattern
="/**/*.gif"
filters
="none"
/>
<
intercept-url
pattern
="/**/*.css"
filters
="none"
/>
<
intercept-url
pattern
="/**/*.js"
filters
="none"
/>
<!--
登录页面和忘记密码页面不过滤
-->
<
intercept-url
pattern
="/login.jsp"
filters
="none"
/>
<
intercept-url
pattern
="/jsp/forgotpassword.jsp"
filters
="none"
/>

<!--
下面是对Action配置。表示具有访问/unitsManager资源的用户必须具有ROLE_PLATFORMADMIN的权限。
当用户登录时,SS3将用户的所有权限从数据库中提取出来,形成列表。 当用户访问该资源时,SS3将
登录用户的权限列表提出来跟下面配置的权限进行比对,若有,则允许访问,若没有,则给出AccessDeniedException。
-->
<
intercept-url
pattern
="/unitsManager"
access
="ROLE_PLATFORMADMIN"
/>
<
intercept-url
pattern
="/usersManager"
access
="ROLE_PLATFORMADMIN"
/>

<
intercept-url
pattern
="/horizontalQuery"
access
="ROLE_PLATFORMADMIN"
/>
<
intercept-url
pattern
="/verticalQuery"
access
="ROLE_PLATFORMADMIN"
/>
<
form-login
login-page
="/login.jsp"
authentication-failure-url
="/login.jsp?error=true"
default-target-url
="/index.jsp"
/>

<!--
"记住我"功能,采用持久化策略(将用户的登录信息存放在数据库表中)
-->
<
remember-me
data-source-ref
="dataSource"
/>
<!--
检测失效的sessionId,超时时定位到另外一个URL
-->
<
session-management
invalid-session-url
="/sessionTimeout.jsp"
/>
</
http
>

<!--
注意能够为authentication-manager 设置alias别名
-->
<
authentication-manager
alias
="authenticationManager"
>
<
authentication-provider
user-service-ref
="userDetailsManager"
>
<
password-encoder
ref
="passwordEncoder"
>
<!--
用户名做为盐值
-->
<
salt-source
user-property
="username"
/>
</
password-encoder
>
</
authentication-provider
>
</
authentication-manager
>

</
b:beans
>
2、applicationContext.service.xml:
<
beans
xmlns
="http://www.springframework.org/schema/beans"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util
="http://www.springframework.org/schema/util"
xmlns:jee
="http://www.springframework.org/schema/jee"
xmlns:aop
="http://www.springframework.org/schema/aop"
xmlns:tx
="http://www.springframework.org/schema/tx"
xmlns:context
="http://www.springframework.org/schema/context"
xsi:schemaLocation
="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd"
>
<!--
定义上下文返回的消息的国际化。
-->
<
bean
id
="messageSource"
class
="org.springframework.context.support.ReloadableResourceBundleMessageSource"
>
<
property
name
="basename"
value
="classpath:org/springframework/security/messages_zh_CN"
/>
</
bean
>

<!--
事件监听:实现了 ApplicationListener监听接口,包括AuthenticationCredentialsNotFoundEvent 事件,
AuthorizationFailureEvent事件,AuthorizedEvent事件, PublicInvocationEvent事件
-->
<
bean
class
="org.springframework.security.authentication.event.LoggerListener"
/>

<!--
用户的密码加密或解密
-->
<
bean
id
="passwordEncoder"
class
="org.springframework.security.authentication.encoding.Md5PasswordEncoder"
/>


<!--
用户详细信息管理 : 数据源、用户缓存、启用用户组功能。
-->
<
bean
id
="userDetailsManager"
class
="org.springframework.security.provisioning.JdbcUserDetailsManager"
>
<
property
name
="dataSource"
ref
="dataSource"
/>
<
property
name
="userCache"
ref
="userCache"
/>
</
bean
>
<
bean
id
="userCache"
class
="org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache"
>
<
property
name
="cache"
ref
="userEhCache"
/>
</
bean
>
<
bean
id
="userEhCache"
class
="org.springframework.cache.ehcache.EhCacheFactoryBean"
>
<
property
name
="cacheName"
value
="userCache"
/>
<
property
name
="cacheManager"
ref
="cacheManager"
/>
</
bean
>
<!--
缓存用户管理
-->
<
bean
id
="cacheManager"
class
="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
/>

<!--
spring security自带的与权限有关的数据读写Jdbc模板
-->
<
bean
id
="jdbcTemplate"
class
="org.springframework.jdbc.core.JdbcTemplate"
>
<
property
name
="dataSource"
ref
="dataSource"
/>
</
bean
>

</
beans
>
3、web.xml:
<
web-app
version
="2.5"
xmlns
="http://java.sun.com/xml/ns/javaee"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
>


<!--
设置log4j存放Log文件位置(通过spring统一进行管理)
-->
<
context-param
>
<
param-name
>
webAppRootKey
</
param-name
>
<
param-value
>
log.root
</
param-value
>
</
context-param
>

<!--
加载log4j的配置文件
-->
<
context-param
>
<
param-name
>
log4jConfigLocation
</
param-name
>
<
param-value
>
classpath:/log4j.properties
</
param-value
>
</
context-param
>

<!--
Spring默认刷新Log4j配置文件的间隔,单位为millisecond
-->
<
context-param
>
<
param-name
>
log4jRefreshInterval
</
param-name
>
<
param-value
>
60000
</
param-value
>
</
context-param
>

<!--
Spring用于log4j初始化的监听器
-->
<
listener
>
<
listener-class
>
org.springframework.web.util.Log4jConfigListener
</
listener-class
>
</
listener
>

<!--
加载Spring XML配置文件,Spring安全配置及各类资源文件,暂不加
/WEB-INF/applicationContext-security.xml,
-->
<
context-param
>
<
param-name
>
contextConfigLocation
</
param-name
>
<
param-value
>
/WEB-INF/applicationContext*.xml,
classpath*:applicationContext.xml
1160

被折叠的 条评论
为什么被折叠?



