//数据库脚本:mysql.sql
DROP DATABASE IF EXISTS sampledb;
CREATE DATABASE sampledb DEFAULT CHARACTER SET utf8;
USE sampledb;
CREATE TABLE T_USER (
USER_ID INTEGER NOT NULL AUTO_INCREMENT,
USERNAME VARCHAR(30) NOT NULL,
PASSWORD VARCHAR(30) DEFAULT NULL,
STATUS TINYINT(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`USER_ID`),
UNIQUE KEY `USERNAME` (`USERNAME`)
);
CREATE TABLE T_USER_PRIV (
USER_ID INTEGER NOT NULL DEFAULT '0',
PRIV_NAME VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (USER_ID, PRIV_NAME)
);
INSERT INTO T_USER (USER_ID, USERNAME, PASSWORD, STATUS) VALUES
(1,'tom','tom',1),
(2,'john','john',1);
INSERT INTO T_USER_PRIV (USER_ID, PRIV_NAME) VALUES
(1,'PRIV_1'),
(1,'PRIV_2'),
(1,'PRIV_COMMON'),
(2,'PRIV_1'),
(2,'PRIV_COMMON');
COMMIT;
在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">
<context-param> <!-- 指定配置文件的相对位置 -->
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml,
classpath:applicationContext-acegi-plugin.xml
</param-value>
</context-param>
<filter> <!-- 创建Acegi 安全过滤器的的代理对象 -->
<filter-name>AcegiFilterChainProxy</filter-name>
<filter-class>
org.acegisecurity.util.FilterToBeanProxy
</filter-class>
<!-- org.acegisecurity.util.FilterChainProxy 这个对象将在spring的配置文件中 -->
<init-param>
<param-name>targetClass</param-name>
<param-value>
org.acegisecurity.util.FilterChainProxy
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>AcegiFilterChainProxy</filter-name>
<url-pattern>/*</url-pattern> <!-- 这个过滤器将拦截所有请求 -->
</filter-mapping>
<listener> <!-- Spring的上下文的监听器 -->
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.acegisecurity.ui.session.HttpSessionEventPublisher
</listener-class>
</listener>
<!--session 超时定义-->
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<!--默认首页定义-->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
下面我们来看看spring的配置文件
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--
/**=channelProcessingFilter,httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,concurrentSessionFilter,filterInvocationInterceptor
-->
<!-- 创建代理对象 -->
<bean id="filterChainProxy"
class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_UPPERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT /**=channelProcessingFilter,httpSessionContextIntegrationFilter,authenticationProcessingFilter,logoutFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,concurrentSessionFilter,filterSecurityInterceptor
</value>
</property>
</bean>
<!--CONVERT_URL_TO_UPPERCASE_BEFORE_COMPARISON表示的是判读的是URL 而 PATTERN_TYPE_APACHE_ANT 表示是的使用的是ANT的路径风格进行配置匹配的URL 如果不写Acgi将使用正则表达式来解析这个URL 这个地方不要使用会出或换行 -->
<!-- authenticationProcessingFilter 使用认证的处理器过滤匹配的URL -->
<!--
每次request前 HttpSessionContextIntegrationFilter从Session中获取Authentication对象,在request完后
又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前使用
-->
<bean id="httpSessionContextIntegrationFilter"
class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />
<!--
和servlet spec差不多,处理登陆请求
authenticationFailureUrl定义登陆失败时转向的页面
defaultTargetUrl定义登陆成功时转向的页面
filterProcessesUrl定义登陆请求的页面
rememberMeServices用于在验证成功后添加cookie信息
-->
<bean id="authenticationProcessingFilter"
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationFailureUrl" value="/index.jsp?login_error=1" /><!-- 认证失败后的URL -->
<property name="defaultTargetUrl" value="/main.jsp" /><!-- 跳转后的URL -->
<property name="filterProcessesUrl" value="/j_acegi_security_check" /><!-- 要过滤的URL -->
<property name="rememberMeServices" ref="rememberMeServices" /><!-- 登录时将用户名或密码保存到 cookie 中 -->
</bean>
<!-- 认证的处理过滤器 -->
<bean id="authenticationManager"
class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider" />
<bean class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="baobaotao" />
</bean>
<ref local="anonymousAuthenticationProvider" />
</list>
</property>
<property name="sessionController" ref="concurrentSessionController"/>
</bean>
<!-- 基于数据库存储的用户信息获取 -->
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<!--#1 -->
</bean>
<!-- 基于数据库的中使用列表的对象 org.acegisecurity.userdetails.jdbc.JdbcDaoImpl 这个处理类是固定的 -->
<bean id="userDetailsService"
class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource" />
<property name="usersByUsernameQuery">
<value>
SELECT username,password,1 FROM t_user WHERE status='1'
AND username = ?
</value>
<!-- 根据用户名查询用户的SQL语句 -->
</property>
<property name="authoritiesByUsernameQuery">
<value>
SELECT u.username,p.priv_name FROM t_user u,t_user_priv
p WHERE u.user_id =p.user_id AND u.username = ?
</value>
<!-- 根据用户名查询用户权限的sql语句 -->
</property>
</bean>
//jdbcDaoImpl通过usersByUsernameQuery和authoritiesByUsernameQuery属性的定义查询用户信息和用户的权限的sql语句,实际上jdbcDaoImpl为以上两个属性提供了默认