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>
- <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>
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app>
- <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>
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<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"/>
- </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>
- <?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"/>
- </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>
<?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"/>
</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>
[list=A]其中filterChainProxy就是由web.xml声明的filter(FilterToBeanProxy)的targetClass。它主要是装载filterInvocationDefinitionSource指定的filter类(例子中为authenticationProcessingFilter,exceptionTranslationFilter),并顺序调用它们的doFilter方法,进行安全服务处理。[/list]
[list=B]而authenticationProcessingFilter是处理一个认证表单,登陆用的表单必须提交用户名和密码这两个参数给这个filter.由用户名和密码构造一个UsernamePasswordAuthenticationToken,将传给AuthenticationManager的authenticate方法进行认证处理。该filter默认处理filterProcessesUrl属性指定的URL,认证失败会转到authenticationFailureUrl,认证成功会转到defaultTargetUrl页面。[/list]
[list=C]AuthenticationManager顾名思义认证管理器,它只有一个接口方法authenticate用于返回认证结果,他的实现类由多个AuthenticationProvider进行投票,决定认证是否通过。[/list]
[list=D]daoAuthenticationProvider是检验用户录入的认证数据是否正确(说白了就是用户名和密码是否正确)[/list]
[list=E]inMemoryDaoImpl是给daoAuthenticationProvider提供系统的用户资料。而资料的来源是从配置中装载到内存的。[/list]
[list=F]当认证不通过时,AuthenticationManager的实现类AbstractAuthenticationManager会抛出AuthenticationException类型的异常。这时排在最后的exceptionTranslationFilter会捕获该异常,并转向authenticationEntryPoint。[/list]
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=userinfo.jsp">
- </head>
- <body>
- <p>Loading ...</p>
- </body>
- </html>
- <%@ 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=userinfo.jsp">
- </head>
- <body>
- <p>Loading ...</p>
- </body>
- </html>
<%@ 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=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.*"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <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">
- </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>
- <%@ page language="java" pageEncoding="UTF-8"%>
- <%@ page import="org.acegisecurity.context.SecurityContextHolder"%>
- <%@ page import="org.acegisecurity.userdetails.*"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
- <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">
- </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>
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page import="org.acegisecurity.context.SecurityContextHolder"%>
<%@ page import="org.acegisecurity.userdetails.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<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">
</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