??????最近兩星期在學習acegi,過程中感謝JavaEye,SpringSide和在網上提供acegi學習心得的網友們。
為了加深自己的認識,準備寫下一些DEMO,希望可以給準備學習acegi的同學一些幫助。
??????作為安全服務離不開認證和授權這兩個主要組成部分。而這篇文章就是針對acegi的認證服務。
??????????????????????????????????????????????????????????????????????????????學習Acegi-認證(authentication)
代碼環境基于:
JDK1.5
acegi1.0.3
spring2.0
IDE基于:
Eclipse3.2+MyEclipse5.0.1
面向人員:
熟悉Eclipse+MyEclipse開發但剛開始了解acegi的人員。如果你是高手請指出文章不足之處。
1.建立一個MyEclipse的WebProject,把下列jar文件拷貝到項目的WEB-INF/lib目錄:
acegi-security-1.0.3.jar
spring2.0.jar
commons-codec-1.3.jar
費話說一句(占些字數
):這是因為代碼運行需要這些包的支持。
2.修改WEB-INF下的web.xml文件,內容如下:
<?
xml?version
=
"
1.0
"
?encoding
=
"
UTF-8
"
?>
<
web
-
app?version
=
"
2.4
"
?xmlns
=
"
http://java.sun.com/xml/ns/j2ee
"
????xmlns:xsi
=
"
http://www.w3.org/2001/XMLSchema-instance
"
????xsi:schemaLocation
=
"
http://java.sun.com/xml/ns/j2ee?
????http:
//
java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
????
<
display
-
name
>
acegi?Example?of?liuyxit
</
display
-
name
>
????
????
<!--
????????定義應用的上下文參數,用于ContextLoaderListener??????
????
-->
????
<
context
-
param
>
????????
<
param
-
name
>
contextConfigLocation
</
param
-
name
>
????????
<
param
-
value
>
????????????classpath:spring
/
applicationContext.xml
????????
</
param
-
value
>
????
</
context
-
param
>
????
<!--
acegi?的filter鏈代理
-->
????
<
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>
????<!--
????????裝載應用軟件的Spring上下文
????????要由WebapplicationContextUtils.getWebApplicationnContext(servletContext)得到.
????-->
????<listener>
????????<listener-class>
????????????org.springframework.web.context.ContextLoaderListener
????????</listener-class>
????</listener>
</web-app>
其中FilterChainProxy實現了filter接口,它主要是實例化FilterChainProxy,并把所有動作交由FilterChainProxy處理。這樣簡化了web.xml的配置,并且充分利用了Spring IOC管理Bean的優勢。
3.在src目錄右鍵新建一個resource folder,在下面再建立acegi和spring目錄
在spring目錄中創建applicationContext.xml文件,內容:
<?
xml?version
=
"
1.0
"
?encoding
=
"
UTF-8
"
?>
<
beans?xmlns
=
"
http://www.springframework.org/schema/beans
"
???????xmlns:xsi
=
"
http://www.w3.org/2001/XMLSchema-instance
"
???????xmlns:aop
=
"
http://www.springframework.org/schema/aop
"
???????xmlns:tx
=
"
http://www.springframework.org/schema/tx
"
???????xsi:schemaLocation
=
"
http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
???????????http:
//
www.springframework.org/schema/aop?
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
???????????http:
//
www.springframework.org/schema/tx?
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
"
???????
default
-
autowire
=
"
byName
"
?
default
-
lazy
-
init
=
"
true
"
>
????
????
<!--
?
========================
?FILTER?CHAIN?
=======================
?
-->
????
<
bean?id
=
"
filterChainProxy
"
?
class
=
"
org.acegisecurity.util.FilterChainProxy
"
>
??????
<
property?name
=
"
filterInvocationDefinitionSource
"
>
?????????
<
value
>
????????????CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
????????????PATTERN_TYPE_APACHE_ANT
????????????
/**
=authenticationProcessingFilter,exceptionTranslationFilter
?????????</value>
??????</property>
????</bean>???
????<!--?========================?認證filter?=======================?-->
???
????<!--?表單認證處理filter?-->
????<bean?id="authenticationProcessingFilter"?class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
????????<property?name="authenticationManager"?ref="authenticationManager"/>
????????<property?name="authenticationFailureUrl"?value="/acegilogin.jsp?login_error=1"/>
????????<property?name="defaultTargetUrl"?value="/userinfo.jsp"/>
????????<property?name="filterProcessesUrl"?value="/j_acegi_security_check"/>
????</bean>????
???????
???<!--?認證管理器?-->
???<bean?id="authenticationManager"?class="org.acegisecurity.providers.ProviderManager">
??????<property?name="providers"><!--?可有多個認證提供器,其中一個證通過就可以了?-->
?????????<list>
????????????<ref?local="daoAuthenticationProvider"/>
????????????<ref?local="rememberMeAuthenticationProvider"/>
?????????</list>
??????</property>
???</bean>???
????<bean?id="daoAuthenticationProvider"?class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
????????<property?name="userDetailsService"?ref="inMemoryDaoImpl"/>????????
????</bean>????
????<!-- 用戶資料-->
?????<bean?id="inMemoryDaoImpl"?class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">??
????????<property?name="userMap">??
????????????<value>??
????????????????liuyxit=123,ROLE_SUPERVISOR
????????????????user1=user1,ROLE_USER
????????????????user2=user2,disabled,ROLE_USER???
????????????</value>??
????????</property>??
????</bean>
????<!--?異常處理filter?-->
????<bean?id="exceptionTranslationFilter"?class="org.acegisecurity.ui.ExceptionTranslationFilter">
????????<property?name="authenticationEntryPoint">
????????????<bean?class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
????????????????<property?name="loginFormUrl"?value="/acegilogin.jsp"/>
????????????????<property?name="forceHttps"?value="false"/>
????????????</bean>
????????</property>
????????<property?name="accessDeniedHandler">
????????????<bean?class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
????????????????<property?name="errorPage"?value="/accessDenied.jsp"/>
????????????</bean>
????????</property>
????</bean>????
</beans>
其中filterChainProxy就是由web.xml聲明的filter(FilterToBeanProxy)的targetClass。它主要是裝載filterInvocationDefinitionSource指定的filter類(例子中為authenticationProcessingFilter,exceptionTranslationFilter),并順序調用它們的doFilter方法,進行安全服務處理。
而authenticationProcessingFilter是處理一個認證表單,登陸用的表單必須提交用戶名和密碼這兩個參數給這個filter.由用戶名和密碼構造一個UsernamePasswordAuthenticationToken,將傳給AuthenticationManager的authenticate方法進行認證處理。該filter默認處理filterProcessesUrl屬性指定的URL,認證失敗會轉到authenticationFailureUrl,認證成功會轉到defaultTargetUrl頁面。
AuthenticationManager顧名思義認證管理器,它只有一個接口方法authenticate用于返回認證結果,他的實現類由多個AuthenticationProvider進行投票,決定認證是否通過。
daoAuthenticationProvider是檢驗用戶錄入的認證數據是否正確(說白了就是用戶名和密碼是否正確)
inMemoryDaoImpl是給daoAuthenticationProvider提供系統的用戶資料。而資料的來源是從配置中裝載到內存的。
當認證不通過時,AuthenticationManager的實現類AbstractAuthenticationManager會拋出AuthenticationException類型的異常。這時排在最后的exceptionTranslationFilter會捕獲該異常,并轉向authenticationEntryPoint。
4.在WebRoot下創建index.jsp(其實不要也沒關系,主要是為了方便),直接轉向用戶資料顯示頁。內容如下
<%
@?page?language
=
"
java
"
?pageEncoding
=
"
UTF-8
"
%>
<!
DOCTYPE?HTML?PUBLIC?
"
-//W3C//DTD?HTML?4.0?Transitional//EN
"
>
<
html
>
<
head
>
???
<!--
?
???????
<
META?HTTP
-
EQUIV
=
"
Refresh
"
?CONTENT
=
"
0;URL=user!list.rgb
"
>
????
-->
?
????
<
META?HTTP
-
EQUIV
=
"
Refresh
"
?CONTENT
=
"
0;URL=userinfo.jsp
"
>
</
head
>
<
body
>
<
p
>
Loading?
</
p
>
</
body
>
</
html
>
5.在WebRoot下創建userinfo.jsp,用于顯示當前登陸的用戶信息。內容如下
<%
@?page?language
=
"
java
"
?pageEncoding
=
"
UTF-8
"
%>
<%
@?page?
import
=
"
org.acegisecurity.context.SecurityContextHolder
"
%>
<%
@?page?
import
=
"
org.acegisecurity.userdetails.*
"
%>
<%
????String?path?
=
?request.getContextPath();
????String?basePath?
=
?request.getScheme()?
+
?
"
://
"
????????????
+
?request.getServerName()?
+
?
"
:
"
?
+
?request.getServerPort()
????????????
+
?path?
+
?
"
/
"
;
%>
<!
DOCTYPE?HTML?PUBLIC?
"
-//W3C//DTD?HTML?4.01?Transitional//EN
"
>
<
html
>
????
<
head
>
????????
<
base?href
=
"
<%=basePath%>
"
>
????????
<
title
>
My?JSP?
'
pass.jsp
'
?starting?page
</
title
>
????????
<
meta?http
-
equiv
=
"
pragma
"
?content
=
"
no-cache
"
>
????????
<
meta?http
-
equiv
=
"
cache-control
"
?content
=
"
no-cache
"
>
????????
<
meta?http
-
equiv
=
"
expires
"
?content
=
"
0
"
>
????????
<
meta?http
-
equiv
=
"
keywords
"
?content
=
"
keyword1,keyword2,keyword3
"
>
????????
<
meta?http
-
equiv
=
"
description
"
?content
=
"
This?is?my?page
"
>
????????
<!--
????
<
link?rel
=
"
stylesheet
"
?type
=
"
text/css
"
?href
=
"
styles.css
"
>
????
-->
????
</
head
>
????
<
body
>
????????當前用戶:
????????
<%
????????????Object?obj?
=
?SecurityContextHolder.getContext().getAuthentication();????????
????????????
if
?(
null
?
!=
?obj){
????????????????Object?userDetail?
=
?SecurityContextHolder.getContext().getAuthentication().getPrincipal();
????????????????String?username?
=
?
""
;
????????????????
if
?(userDetail?
instanceof
?UserDetails)?{
????????????????????username?
=
?((UserDetails)?userDetail).getUsername();
????????????????}?
else
?{
????????????????????username?
=
?userDetail.toString();
????????????????}
????????????????out.print(username);
????????????????out.print(
"
<br><a?href=\
"
j_acegi_logout\
"
>注銷</a>
"
);
????????????}
else
{
????????????????out.print(
"
當前沒有有效的用戶
"
);
????????????????out.print(
"
<br><a?href=\
"
acegilogin.jsp\
"
>登陸</a>
"
);
????????????}
????????
%>
????????
????????
????
</
body
>
</
html
>
?
6.在WebRoot下創建acegilogin.jsp
<%
@?page?language
=
"
java
"
?pageEncoding
=
"
UTF-8
"
%>
<%
@?page?
import
=
"
org.acegisecurity.ui.AbstractProcessingFilter
"
?
%>
<%
@?page?
import
=
"
org.acegisecurity.ui.webapp.AuthenticationProcessingFilter
"
?
%>
<%
@?page?
import
=
"
org.acegisecurity.AuthenticationException
"
?
%>
<
html
>
??
<
head
>
????
<
title
>
Login
</
title
>
??
</
head
>
??
<
body
>
????
<
h1
>
Login
</
h1
>
????
<
P
>
Valid?users:
????
<
P
>
????
<
P
>
username?
<
b
>
liuyxit
</
b
>
,?password?
<
b
>
123
</
b
>
?(supervisor)
????
<
P
>
username?
<
b
>
user1
</
b
>
,?password?
<
b
>
user1
</
b
>
?(normal?user)
????
<
p
>
username?
<
b
>
user2
</
b
>
,?password?
<
b
>
user2
</
b
>
?(user?disabled)
????
<
p
>
????
<%
????????String?strError?
=
?request.getParameter(
"
login_error
"
);
????????
????????
if
?(
null
?
!=
?strError){?
?????
%>
??????
<
font?color
=
"
red
"
>
????????你的登陸失敗,請重試。
<
BR
><
BR
>
?????????原因:?
<%=
?((AuthenticationException)?session.getAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY)).getMessage()?
%>
??????
</
font
>
??????
<%
??????????}
//
end?if
??????
%>
????
<
form?action
=
"
j_acegi_security_check
"
?method
=
"
POST
"
>
??????
<
table
>
????????
<
tr
><
td
>
User:
</
td
><
td
><
input?type
=
'
text
'
?name
=
'
j_username
'
?value
=
'
<%=?session.getAttribute(AuthenticationProcessingFilter.ACEGI_SECURITY_LAST_USERNAME_KEY)?%>
'
></
td
></
tr
>
????????
<
tr
><
td
>
Password:
</
td
><
td
><
input?type
=
'
password
'
?name
=
'
j_password
'
></
td
></
tr
>
????????
<
tr
><
td
><
input?type
=
"
checkbox
"
?name
=
"
_acegi_security_remember_me
"
></
td
><
td
>
2周內自動登錄
</
td
></
tr
>
????????
<
tr
><
td?colspan
=
'
2
'
><
input?name
=
"
submit
"
?type
=
"
submit
"
></
td
></
tr
>
????????
<
tr
><
td?colspan
=
'
2
'
><
input?name
=
"
reset
"
?type
=
"
reset
"
></
td
></
tr
>
??????
</
table
>
????
</
form
>
??
</
body
>
</
html
>
7.OK,發布項目,訪問http://localhost:8080/acegiexample
這時index.jsp會自動轉向userinfo.jsp,由于還沒有用戶登錄,所以沒有資料顯示。按登陸鏈接進入登錄頁,登錄成功后會看到顯示用戶名的頁面(當然可以有更多的用戶資料,但這僅僅是example),不成功時會在登錄頁提示信息。我們可以用user1和user2登陸,可以分別測試登錄成功和失敗的流程。
8.可以看到登錄頁上有自動登陸功能,而userinfo.jsp頁有注銷功能。但還是不起作用,好,現在我們馬上首手加入這兩個功能。看acegi可以方便到什么程度。在applicationContext.xml中加入如下紅色部分:
<?
xml?version
=
"
1.0
"
?encoding
=
"
UTF-8
"
?>
<
beans?xmlns
=
"
http://www.springframework.org/schema/beans
"
???????xmlns:xsi
=
"
http://www.w3.org/2001/XMLSchema-instance
"
???????xmlns:aop
=
"
http://www.springframework.org/schema/aop
"
???????xmlns:tx
=
"
http://www.springframework.org/schema/tx
"
???????xsi:schemaLocation
=
"
http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
???????????http:
//
www.springframework.org/schema/aop?
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
???????????http:
//
www.springframework.org/schema/tx?
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
"
???????
default
-
autowire
=
"
byName
"
?
default
-
lazy
-
init
=
"
true
"
>
????
????
<!--
?
========================
?FILTER?CHAIN?
=======================
?
-->
????
<
bean?id
=
"
filterChainProxy
"
?
class
=
"
org.acegisecurity.util.FilterChainProxy
"
>
??????
<
property?name
=
"
filterInvocationDefinitionSource
"
>
?????????
<
value
>
????????????CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
????????????PATTERN_TYPE_APACHE_ANT
????????????
/**
=authenticationProcessingFilter,logoutFilter,rememberMeProcessingFilter,exceptionTranslationFilter
?????????</value>
??????</property>
????</bean>???
????<!--?========================?認證filter?=======================?-->
???
????<!--?表單認證處理filter?-->
????<bean?id="authenticationProcessingFilter"?class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
????????<property?name="authenticationManager"?ref="authenticationManager"/>
????????<property?name="authenticationFailureUrl"?value="/acegilogin.jsp?login_error=1"/>
????????<property?name="defaultTargetUrl"?value="/userinfo.jsp"/>
????????<property?name="filterProcessesUrl"?value="/j_acegi_security_check"/>
????</bean>
????
????<!--?利用cookie自動登陸filter?-->
????<bean?id="rememberMeProcessingFilter"
??????????class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
????????<property?name="authenticationManager"
??????????????????ref="authenticationManager"/>
????????<property?name="rememberMeServices"?ref="rememberMeServices"/>
????</bean>????
????<bean?id="rememberMeServices"
??????????class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
????????<property?name="userDetailsService"?ref="inMemoryDaoImpl"/>
????????<property?name="key"?value="javargb"/>
????</bean>??
????<bean?id="rememberMeAuthenticationProvider"
??????????class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
????????<property?name="key"?value="javargb"/>
????</bean>???
????
????<!--?注銷處理filter?-->
????<bean?id="logoutFilter"?class="org.acegisecurity.ui.logout.LogoutFilter">
??????<constructor-arg?value="/acegilogin.jsp"/>?<!--?URL?redirected?to?after?logout?-->
??????<constructor-arg>
?????????<list>
??????????????<ref?bean="rememberMeServices"/>
??????????????<bean?class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
?????????</list>
??????</constructor-arg>
???</bean>
????
???<!--?認證管理器?-->
???<bean?id="authenticationManager"?class="org.acegisecurity.providers.ProviderManager">
??????<property?name="providers"><!--?可有多個認證提供器,其中一個證通過就可以了?-->
?????????<list>
????????????<ref?local="daoAuthenticationProvider"/>
????????????<ref?local="rememberMeAuthenticationProvider"/>
?????????</list>
??????</property>
???</bean>???
????<bean?id="daoAuthenticationProvider"?class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
????????<property?name="userDetailsService"?ref="inMemoryDaoImpl"/>????????
????</bean>????
????<!--?
????<bean?id="inMemoryDaoImpl"?class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
????????<property?name="userProperties">
????????????<bean?class="org.springframework.beans.factory.config.PropertiesFactoryBean">
????????????????<property?name="location"?value="classpath:acegi/users.properties"/>
????????????</bean>
????????</property>
????</bean>
?????-->
?????<bean?id="inMemoryDaoImpl"?class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">??
????????<property?name="userMap">??
????????????<value>??
????????????????liuyxit=123,ROLE_SUPERVISOR
????????????????user1=user1,ROLE_USER
????????????????user2=user2,disabled,ROLE_USER???
????????????</value>??
????????</property>??
????</bean>
????<!--?異常處理filter?-->
????<bean?id="exceptionTranslationFilter"?class="org.acegisecurity.ui.ExceptionTranslationFilter">
????????<property?name="authenticationEntryPoint">
????????????<bean?class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
????????????????<property?name="loginFormUrl"?value="/acegilogin.jsp"/>
????????????????<property?name="forceHttps"?value="false"/>
????????????</bean>
????????</property>
????????<property?name="accessDeniedHandler">
????????????<bean?class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
????????????????<property?name="errorPage"?value="/accessDenied.jsp"/>
????????????</bean>
????????</property>
????</bean>????
</beans>
另要注意:Acegi默認的自動登陸設定參數名為_acegi_security_remember_me,注銷鏈接為/j_acegi_logout。
馬上重啟Tomcat測試看看^_^。
9.通常用戶資料會放在數據庫中,而不會放在配置文件,接著下面我們來再行修改一下。
首先創建要用到的用戶表和權限表,并插入初始化數據:
CREATE?TABLE?USERS(
USERNAME?VARCHAR(
50
)?NOT?NULL?PRIMARY?KEY,
PASSWORD?VARCHAR(
50
)?NOT?NULL,
ENABLED?BIT?NOT?NULL)
INSERT?INTO?USERS(username,password,enabled)?values(
'
liuyxit
'
,
'
123
'
,
'
1
'
)
INSERT?INTO?USERS(username,password,enabled)?values(
'
user1
'
,
'
user1
'
,
'
1
'
)
INSERT?INTO?USERS(username,password,enabled)?values(
'
user2
'
,
'
user2
'
,
'
0
'
)
CREATE?TABLE?AUTHORITIES(
USERNAME?VARCHAR(
50
)?NOT?NULL,
AUTHORITY?VARCHAR(
50
)?NOT?NULL,
CONSTRAINT?FK_AUTHORITIES_USERS?FOREIGN?KEY(USERNAME)?REFERENCES?USERS(USERNAME)
);
INSERT?INTO?AUTHORITIES(USERNAME,AUTHORITY)?values(
'
liuyxit
'
,
'
ROLE_SUPERVISOR
'
)
INSERT?INTO?AUTHORITIES(USERNAME,AUTHORITY)?values(
'
user1
'
,
'
ROLE_USER
'
)
INSERT?INTO?AUTHORITIES(USERNAME,AUTHORITY)?values(
'
user2
'
,
'
ROLE_USER
'
)
這里我用的是acegi默認的數據結構,可以改只要你指定JdbcDaoImpl的authoritiesByUsernameQuery和usersByUsernameQuery屬性就可以了。另AUTHORITIES表也要一同加入,原因acegi獲得userDetail時,也會讀取這個表的內容,否則會拋“nested exception is java.sql.SQLException: 對象名 'authorities' 無效”這個異常。
修改applicationContext.xml,變成如下:
<?
xml?version="1.0"?encoding="UTF-8"
?>
<
beans?
xmlns
="http://www.springframework.org/schema/beans"
???????xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
???????xmlns:aop
="http://www.springframework.org/schema/aop"
???????xmlns:tx
="http://www.springframework.org/schema/tx"
???????xsi:schemaLocation
="http://www.springframework.org/schema/beans?http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
???????????http://www.springframework.org/schema/aop?http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
???????????http://www.springframework.org/schema/tx?http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
???????default-autowire
="byName"
?default-lazy-init
="true"
>
????
????
<
bean?
id
="dataSource"
?class
="org.springframework.jdbc.datasource.DriverManagerDataSource"
>
????????
<
property?
name
="driverClassName"
>
????????????
<!--
?請自行修改為對應你的數據庫的驅動類?
-->
????????????
<
value
>
net.sourceforge.jtds.jdbc.Driver
</
value
>
????????????
????????
</
property
>
????????
<
property?
name
="url"
>
????????????
<!--
?請自行修改為對應你的數據庫URL?
-->
????????????
<
value
>
jdbc:jtds:sqlserver://localhost:1433/javauser
</
value
>
????????
</
property
>
????????
<
property?
name
="username"
>
????????????
<
value
>
sa
</
value
>
????????
</
property
>
????????
<
property?
name
="password"
>
????????????
<
value
>
javauser
</
value
>
????????
</
property
>
????
</
bean
>
??
????
<!--
?========================?FILTER?CHAIN?=======================?
-->
????
<
bean?
id
="filterChainProxy"
?class
="org.acegisecurity.util.FilterChainProxy"
>
??????
<
property?
name
="filterInvocationDefinitionSource"
>
?????????
<
value
>
????????????CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
????????????PATTERN_TYPE_APACHE_ANT
????????????/**=authenticationProcessingFilter,logoutFilter,rememberMeProcessingFilter,exceptionTranslationFilter
?????????
</
value
>
??????
</
property
>
????
</
bean
>
???
????
<!--
?========================?認證filter?=======================?
-->
???
????
<!--
?表單認證處理filter?
-->
????
<
bean?
id
="authenticationProcessingFilter"
?class
="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"
>
????????
<
property?
name
="authenticationManager"
?ref
="authenticationManager"
/>
????????
<
property?
name
="authenticationFailureUrl"
?value
="/acegilogin.jsp?login_error=1"
/>
????????
<
property?
name
="defaultTargetUrl"
?value
="/userinfo.jsp"
/>
????????
<
property?
name
="filterProcessesUrl"
?value
="/j_acegi_security_check"
/>
????
</
bean
>
????
????
<!--
?利用cookie自動登陸filter?
-->
????
<
bean?
id
="rememberMeProcessingFilter"
??????????class
="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter"
>
????????
<
property?
name
="authenticationManager"
??????????????????ref
="authenticationManager"
/>
????????
<
property?
name
="rememberMeServices"
?ref
="rememberMeServices"
/>
????
</
bean
>
????
????
<
bean?
id
="rememberMeServices"
??????????class
="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices"
>
????????
<
property?
name
="userDetailsService"
?ref
="jdbcDaoImpl"
/>
????????
<
property?
name
="key"
?value
="javargb"
/>
????
</
bean
>
??
????
<
bean?
id
="rememberMeAuthenticationProvider"
??????????class
="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider"
>
????????
<
property?
name
="key"
?value
="javargb"
/>
????
</
bean
>
???
????
????
<!--
?注銷處理filter?
-->
????
<
bean?
id
="logoutFilter"
?class
="org.acegisecurity.ui.logout.LogoutFilter"
>
??????
<
constructor-arg?
value
="/acegilogin.jsp"
/>
?
<!--
?URL?redirected?to?after?logout?
-->
??????
<
constructor-arg
>
?????????
<
list
>
??????????????
<
ref?
bean
="rememberMeServices"
/>
??????????????
<
bean?
class
="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"
/>
?????????
</
list
>
??????
</
constructor-arg
>
???
</
bean
>
????
???
<!--
?認證管理器?
-->
???
<
bean?
id
="authenticationManager"
?class
="org.acegisecurity.providers.ProviderManager"
>
??????
<
property?
name
="providers"
>
<!--
?可有多個認證提供器,其中一個證通過就可以了?
-->
?????????
<
list
>
????????????
<
ref?
local
="daoAuthenticationProvider"
/>
????????????
<
ref?
local
="rememberMeAuthenticationProvider"
/>
?????????
</
list
>
??????
</
property
>
???
</
bean
>
???
????
<
bean?
id
="daoAuthenticationProvider"
?class
="org.acegisecurity.providers.dao.DaoAuthenticationProvider"
>
????????
<
property?
name
="userDetailsService"
?ref
="jdbcDaoImpl"
/>
????????
????
</
bean
>
????
????
????
<
bean?
id
="jdbcDaoImpl"
?class
="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl"
>
????????
<
property?
name
="dataSource"
><
ref?
bean
="dataSource"
/></
property
>
????
</
bean
>
????
????
<!--
?異常處理filter?
-->
????
<
bean?
id
="exceptionTranslationFilter"
?class
="org.acegisecurity.ui.ExceptionTranslationFilter"
>
????????
<
property?
name
="authenticationEntryPoint"
>
????????????
<
bean?
class
="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"
>
????????????????
<
property?
name
="loginFormUrl"
?value
="/acegilogin.jsp"
/>
????????????????
<
property?
name
="forceHttps"
?value
="false"
/>
????????????
</
bean
>
????????
</
property
>
????????
<
property?
name
="accessDeniedHandler"
>
????????????
<
bean?
class
="org.acegisecurity.ui.AccessDeniedHandlerImpl"
>
????????????????
<
property?
name
="errorPage"
?value
="/accessDenied.jsp"
/>
????????????
</
bean
>
????????
</
property
>
????
</
bean
>
????
</
beans
>
這時userDetailsService是通過實現類jdbcDaoImpl從數據庫獲得用戶資料來作認證比較。
OK,大功告成。
后記:很少寫技術文章,除了要堅持之外,文筆和思路都很重要。感覺自己的寫作水平太差了,希望大家指出不合理的地方。有時間我會再寫后篇《學習Acegi-授權(authorization)》,感謝大家把拙文看完,TKS!
posted on 2007-02-07 14:14
三刀流の逆風 閱讀(1949)
評論(3) 編輯 收藏 所屬分類:
acegi