最近两星期在学习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
三刀流の逆风 阅读(1947)
评论(3) 编辑 收藏 所属分类:
acegi