具體步驟如下:
開發環境:
項目目錄如下: 其中readme主要用來記錄本次驗證目的
配置文件
web.xml:
<?xml version="1.0" encoding= "UTF-8"?>
<web-app xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns= "http://java.sun.com/xml/ns/javaee" xmlns:web= "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version= "2.5">
< display-name></display-name >
<!-- spring 配置文件 -->
< context-param>
<param-name >contextConfigLocation </param-name >
<param-value >
classpath:config/spring/spring-acegi.xml
</param-value >
</ context-param>
<!-- acegi對頁面校驗控制 -->
< filter>
<filter-name >AcegiFilterChainProxy </filter-name >
<filter-class >
org.acegisecurity.util.FilterToBeanProxy
</filter-class >
<init-param >
<param-name >targetBean </param-name >
<param-value >filterChainProxy </param-value >
</init-param >
</ filter>
< filter-mapping>
<filter-name >AcegiFilterChainProxy </filter-name >
<url-pattern >/j_acegi_security_check </url-pattern >
</ filter-mapping>
< filter-mapping>
<filter-name >AcegiFilterChainProxy </filter-name >
<url-pattern >/j_acegi_logout </url-pattern >
</ filter-mapping>
< filter-mapping>
<filter-name >AcegiFilterChainProxy </filter-name >
<url-pattern >*.do </url-pattern >
</ filter-mapping>
< filter-mapping>
<filter-name >AcegiFilterChainProxy </filter-name >
<url-pattern >*.jsp </url-pattern >
</ filter-mapping>
< welcome-file-list>
<welcome-file >index.jsp </welcome-file >
</ welcome-file-list>
<!-- spring配置 -->
< listener>
<listener-class >
org.springframework.web.context.ContextLoaderListener
</listener-class >
</ listener>
</web-app>
acegi配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns= "http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" >
<!-- 通過過濾連形式,acegi提供很多filter,其中過濾器執行也有一定的順序 ,同事支持正則和ant匹配-->
<bean id ="filterChainProxy" class= "org.acegisecurity.util.FilterChainProxy" >
<property name ="filterInvocationDefinitionSource">
<value >
PATTERN_TYPE_APACHE_ANT
/**=authenticationProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value >
</property >
</bean >
<!-- 表單認證處理filter -->
<bean id ="authenticationProcessingFilter" class= "org.acegisecurity.ui.webapp.AuthenticationProcessingFilter" >
<!-- 認證管理器,然後委託給Provides -->
<property name ="authenticationManager" ref= "authenticationManager"/>
<!-- 認證失敗後轉向的url,包含出錯信息的的登陸頁面 -->
<property name ="authenticationFailureUrl" value= "/login.jsp?login_error=1"/>
<!-- 登陸成功後轉向的url -->
<property name ="defaultTargetUrl" value= "/userinfo.jsp"/>
<!-- 登陸的url,這個是默認的acegi自帶的 -->
<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= "inMemDaoImpl" />
</bean >
<!-- 基於內存實現方式-->
<bean id ="inMemDaoImpl"
class= "org.acegisecurity.userdetails.memory.InMemoryDaoImpl" >
<property name ="userMap">
<value >
test=1,ROLE_USER
lisi=1,ROLE_SUPERVISOR
zhangsan=1,ROLE_SUPERVISOR,disabled
</value >
</property >
</bean >
<!-- exception filter -->
<bean id ="exceptionTranslationFilter" class= "org.acegisecurity.ui.ExceptionTranslationFilter" >
<!-- 尚未登錄, 進入非法(未認證不可訪問)區域 -->
<property name ="authenticationEntryPoint">
<bean class= "org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint" >
<property name ="loginFormUrl" value= "/login.jsp"/> <!--若沒登陸,則轉向 用戶登陸頁面 -->
<property name ="forceHttps" value="false"/> <!-- 是否強制使用https -->
</bean >
</property >
<!-- 登錄後, 進入非授權區域 -->
<property name ="accessDeniedHandler">
<bean class= "org.acegisecurity.ui.AccessDeniedHandlerImpl" >
<property name ="errorPage" value= "/accessDenied.jsp"/> <!-- 進入無權限頁面 ,根據需求寫相應的信息-->
</bean >
</property >
</bean >
<bean id ="filterInvocationInterceptor"
class= "org.acegisecurity.intercept.web.FilterSecurityInterceptor" >
<property name ="authenticationManager" ref= "authenticationManager" />
<property name ="accessDecisionManager" ref= "httpRequestAccessDecisionManager" />
<property name ="objectDefinitionSource">
<value ><![CDATA[
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/userinfo.jsp=ROLE_SUPERVISOR
]]></value>
</property >
</bean >
<bean id ="httpRequestAccessDecisionManager"
class= "org.acegisecurity.vote.AffirmativeBased" >
<property name ="decisionVoters">
<list >
<bean class= "org.acegisecurity.vote.RoleVoter" />
</list >
</property >
</bean >
</beans>
講解如下:
頁面如下:
userinfo.jsp:顯示用戶信息
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import= "org.acegisecurity.context.SecurityContextHolder" %>
<%@ page import ="org.acegisecurity.userdetails.*"%>
<html>
<head>
<meta http-equiv= "Content-Type" content ="text/html; charset=UTF-8">
<title> 當前用戶的具體信息 </title >
</head>
<body>
當前用戶:
<%
Object obj = SecurityContextHolder.getContext().getAuthentication();
if ( null != obj){
Object userDetail = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = "";
String pwd= "";
if (userDetail instanceof UserDetails) {
username = ((UserDetails) userDetail).getUsername();
pwd = ((UserDetails) userDetail).getPassword();
} else {
username = userDetail.toString();
}
out.print(username+ ",密碼:"+pwd);
}
%>
</body>
</html>
登陸頁:login.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>
<body >
<%
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 METHOD= POST ACTION ="j_acegi_security_check">
< table>
<tr >
<td >用戶名: </td >
<td ><input NAME ="j_username" type= "text" title ="用戶名" /></td>
</tr >
<tr >
<td > 密碼: </td >
<td ><input name ="j_password" type= "text" title = "密碼"/></td >
</tr >
<tr >
<td > </td >
<td > <input type ="submit" value="登陸"/></ td></ tr>
</ table>
</FORM >
</ body>
其中注意:用戶名和密碼的name必須是j_username和j_password,以及action必須是j_acegi_security_check,這是acegi規則。
測試如下: