Spring的Acegi security的配置,和JDK1.5的一些問題(轉(zhuǎn))
新的項(xiàng)目沒有開始于是抽空做一個(gè)通用一些的 Security, 后來又考慮到 CAS 和 SSL 的認(rèn)證問題俺還沒有弄懂,就選擇直接使用 Spring 的子項(xiàng)目 acegi
acegi
是基于
Spring
的的一個(gè)安全框架,支持
HTTP
基本(
basic
)驗(yàn)證、
HTTP Request Session
驗(yàn)證、安全通道、
ACL
等等,功能強(qiáng)大。配置比較簡(jiǎn)單,但是還是要寫一下:
1.??
下載
Spring Acegi
的
jar
文件和它的源代碼,在它的
binary
包中有一個(gè)
contacts.war
,這個(gè)是
acegi
的示例,把它放在
tomcat
的
webapps
下直接運(yùn)行即可,這個(gè)是
acegi
很好的參考。
2.??
將
acegi
的
Http Servlet Filter
配置在
web.xml
中。
???
<!-- Acegi Security-->
???
<
filter
>
??????
<
filter-name
>
Acegi Filter Chain Proxy
</
filter-name
>
??????
<
filter-class
>
org.acegisecurity.util.FilterToBeanProxy
</
filter-class
>
??????
<
init-param
>
??????????
<
param-name
>
targetClass
</
param-name
>
??????????
<
param-value
>
org.acegisecurity.util.FilterChainProxy
</
param-value
>
??????
</
init-param
>
???
</
filter
>
?
???
<
filter-mapping
>
??????
<
filter-name
>
Acegi Filter Chain Proxy
</
filter-name
>
??????
<
url-pattern
>
/*
</
url-pattern
>
???
</
filter-mapping
>
3.??
將
contract
示例下的
applicationContext-acegi-security.xml
放在
ClassPath
下或
WEB-INF
下,并且在
web.xml
中指出該文件的位置:
<
context-param
>
??????
<
param-name
>
contextConfigLocation
</
param-name
>
??????
<
param-value
>
?????? classpath*:/net/chinasam/common/applicationContext-*.xml
??????
/WEB-INF/ applicationContext-acegi-security.xml
</
param-value
>
???
</
context-param
>
4.??
在
applicationContext-acegi-security.xml
中找到下面的
bean
定義
<
bean
id
=
"jdbcDaoImpl"
class
=
"org.acegisecurity.userdetails.jdbc.JdbcDaoImpl"
>
??????
<
property
name
=
"dataSource"
>
??????????
<
ref
bean
=
"dataSource"
/>
??????
</
property
>
???
</
bean
>
可以看到
dataSource
屬性必須引用一個(gè)
DataSource
,
修改這個(gè)
bean
,
是之使用一個(gè)
Spring
管理的
DataSource
實(shí)例。
JdbcDaoImpl
是查詢數(shù)據(jù)庫的實(shí)現(xiàn)類,這個(gè)類使用下面的
SQL
進(jìn)行查詢:
"SELECT username,password,enabled FROM users WHERE username = ?";
"SELECT username,authority FROM authorities WHERE username = ?";
前者查詢用戶,后者查詢角色,你可以根據(jù)實(shí)際項(xiàng)目的情況進(jìn)行修改:設(shè)置
JdbcDaoImpl
的
authoritiesByUsernameQuery
和
usersByUsernameQuery
屬性。
這個(gè)我沒有設(shè)置過,因?yàn)槲业臄?shù)據(jù)庫結(jié)構(gòu)和這個(gè)一樣。
Acegi
沒有包含用戶管理,關(guān)于
User
的
CRUD
你必須自己完成,然后通過這兩個(gè)屬性告訴
acegi
如何查詢用戶和角色。
???
5.??
密碼編碼,經(jīng)常需要給密碼進(jìn)行編碼,常用的算法包括
MD5
,
SHA
等,
applectionContext –acegi-Security.xml
中的配置為:
<
bean
id
=
"passwordEncoder"
class
=
"org.acegisecurity.providers.encoding.Md5PasswordEncoder"
/>
?
注意,如果使用上述配置,數(shù)據(jù)庫中的
password
字段內(nèi)容必須是實(shí)際內(nèi)容的
MD5
摘要。
6.??
ApplicationContext-acegi-securtiy.xml
缺省的使用
HTTP Request
驗(yàn)證,也就是通過普通的
HTML
標(biāo)單提交用戶名和口令,所以你必須編寫自己的
login
頁面,以下是一個(gè)例子,注意黑體字部分:
<
form
name
=
"login_form"
action
=
"
<
c:url
value
=
'j_acegi_security_check'
/>
"
method
=
"POST"
>
<
table
width
=
"241"
border
=
"0"
cellpadding
=
"0"
cellspacing
=
"0"
align
=
"center"
>
?
<
tr
>
???
<
td
><
img
src
=
"
<
fmt:message
key
=
"login.title.img"
/>
"
width
=
"241"
height
=
"26"
></
td
>
?
</
tr
>
?
<
tr
>
?
<
td
>
?
?
??
<
table
width
=
"241"
align
=
"center"
cellpadding
=
"0"
cellspacing
=
"0"
>
???
?
???
?
<
tr
>
??????
<
td
width
=
"1"
bgcolor
=
"#D2DBE8"
></
td
>
??????
<
td
align
=
"left"
>
<
fmt:message
key
=
"username"
/></
td
>
??????
<
td?
align
=
"left"
>
??????
<
input
type
=
"text"
class
=
"text"
name
=
"j_username"
>
</
td
>
??????
<
td
rowspan
=
"4"
>
??????
<
img
src
=
"
<
fmt:message
key
=
"login.button.img"
/>
"
onclick
=
"javascript:login_form.submit()"
style
=
"cursor:hand"
>
??????
</
td
>
??????
<
td
width
=
"1"
bgcolor
=
"#D2DBE8"
></
td
>
???
?
</
tr
>
???
?
<
tr
>
??????
<
td
width
=
"1"
bgcolor
=
"#D2DBE8"
></
td
>
??????
<
td
align
=
"left"
>
<
fmt:message
key
=
"password"
/></
td
>
??????
<
td
align
=
"left"
>
<
input
type
=
"password"
class
=
"text"
name
=
"j_password"
>
</
td
>
??????
<
td
width
=
"1"
bgcolor
=
"#D2DBE8"
></
td
>
???
?
<
tr
>
??????
<
td
width
=
"1"
bgcolor
=
"#D2DBE8"
></
td
>
??????
<
td
align
=
"left"
colspan
=
"3"
>
<
fmt:message
key
=
"rememberme"
/>
??????
<
input
type
=
"checkbox"
name
=
"_acegi_security_remember_me"
>
</
td
>
??????
<
td
width
=
"1"
bgcolor
=
"#D2DBE8"
></
td
>
???
?
</
tr
>
???
?
</
table
>
?
</
td
></
tr
>
?
<
c:if
test
=
"
${! empty param.login_error}">
?????
<
tr
><
td
><
br
>
?????
<
fmt:message
key
=
"login.failed"
/>
<%=
((AuthenticationException) session.getAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY)).getMessage()
%>
?????
</
td
>
??
</
tr
>
?
</
c:if
>
??
</
table
>
?
</
form
>
最后,你需要配置
URL
權(quán)限,關(guān)于
POJO
的方法權(quán)限俺還沒有弄懂,而且,如果不提供遠(yuǎn)程訪問的情況下,一般來說也不需要。在
ApplicationContext-acegi-securtiy.xml
找到
bean
:
filterInvocationInterceptor
?
這個(gè)是基于
Http Request
驗(yàn)證的權(quán)限
terceptor
,
注意設(shè)置
bjectDefinitionSource
屬性,下面是例子,
URL
的格式是參考
ANT
的格式,也可以根據(jù)正則表達(dá)式的寫法:
<
property
name
=
"objectDefinitionSource"
>
??????????
<
value
>
??????????
<![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/index.faces=ROLE_SUPERVISOR,ROLE_ANONYMOUS,ROLE_USER
/login.jsp*=ROLE_SUPERVISOR,ROLE_ANONYMOUS,ROLE_USER
/images/*.*=ROLE_SUPERVISOR,ROLE_ANONYMOUS,ROLE_USER
/common/*.*=ROLE_SUPERVISOR,ROLE_ANONYMOUS,ROLE_USER
/styles/*.*=ROLE_SUPERVISOR,ROLE_ANONYMOUS,ROLE_USER
/**=ROLE_USER
?????????????
]]>
??????????
</
value
>
各個(gè)權(quán)限入口的順序十分重要,注意必須把特殊的
URL
權(quán)限寫在一般的
URL
權(quán)限之前。
?
7. Acegi
1.0
是基于
JDK1.5
的,雖然你可以在
1
.4
下使用,但是我還是把我的項(xiàng)目改為
JDK1
.5,
沒成想還出現(xiàn)了一些問題。另外
JSTL
的也不同了,如果你想使用
EL
,則必須這樣引用
core
:
<%@
taglib
uri
=
"http://java.sun.com/jstl/core_rt"
prefix
=
"c"
%>
在
JDK1.4
下使用
String.replaceFirst
和
replaceAll
方法沒有問題,但是在
JDK1.5
下卻報(bào)
IllegalArgumentException
,
getMessage
指出
Illegal group arguments
,但是單獨(dú)寫測(cè)試類運(yùn)行卻沒有任何問題,我只好些了自己的
replace
算法,可是總覺得應(yīng)該使用
JDK
提供的,希望達(dá)人指教。
8
.關(guān)于如何使用
ACL
、
SSL
等驗(yàn)證,俺需要進(jìn)一步研究。
posted on 2006-12-22 16:36 junky 閱讀(568) 評(píng)論(0) 編輯 收藏 所屬分類: spring