这里我用的是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!

