在web.xml加入:
<filter> <filter-name>securityFilter</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> <filter-name>AcegiChannelProcessingFilter</filter-name> <filter-class> org.acegisecurity.util.FilterToBeanProxy </filter-class> <init-param> <param-name>targetClass</param-name> <param-value> org.acegisecurity.securechannel.ChannelProcessingFilter </param-value> </init-param> </filter> <filter-mapping> <filter-name>securityFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>AcegiChannelProcessingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
在spring的配置:
<?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" 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"> <!-- ======================== FILTER CHAIN ======================= --> <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"> <property name="filterInvocationDefinitionSource"> <value> CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON PATTERN_TYPE_APACHE_ANT /images/**=#NONE# /scripts/**=#NONE# /styles/**=#NONE# /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor </value> <!-- Put channelProcessingFilter before securityContextHolderAwareRequestFilter to turn on SSL switching --> <!-- It's off by default b/c Canoo WebTest doesn't support SSL out-of-the-box --> </property> </bean> <bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"/> <!-- Changed to use logout.jsp since causes 404 on WebSphere: http://issues.appfuse.org/browse/APF-566 --> <!--bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter"> <constructor-arg value="/index.jsp"/> <constructor-arg> <list> <ref bean="rememberMeServices"/> <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/> </list> </constructor-arg> <property name="filterProcessesUrl" value="/logout.jsp"/> </bean--> <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"> <property name="authenticationManager" ref="authenticationManager"/> <property name="authenticationFailureUrl" value="/login.jsp?error=true"/> <property name="defaultTargetUrl" value="/"/> <property name="filterProcessesUrl" value="/j_security_check"/> <property name="rememberMeServices" ref="rememberMeServices"/> </bean> <bean id="securityContextHolderAwareRequestFilter" class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter"/> <bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter"> <property name="authenticationManager" ref="authenticationManager"/> <property name="rememberMeServices" ref="rememberMeServices"/> </bean> <bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter"> <property name="key" value="anonymous"/> <property name="userAttribute" value="anonymous,ROLE_ANONYMOUS"/> </bean> <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"/> </bean> </property> </bean> <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"> <property name="authenticationManager" ref="authenticationManager"/> <property name="accessDecisionManager" ref="accessDecisionManager"/> <property name="objectDefinitionSource"> <value> PATTERN_TYPE_APACHE_ANT /activeUsers.*=ROLE_ADMIN /clickstreams.jsp*=ROLE_ADMIN /flushCache.*=ROLE_ADMIN /passwordHint.html*=ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER /reload.*=ROLE_ADMIN /signup.html*=ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER /a4j.res/*.html*=ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER <!-- APF-737, OK to remove if not using JSF --> /users.html*=ROLE_ADMIN /**/*.html*=ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER </value> </property> </bean> <bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased"> <property name="allowIfAllAbstainDecisions" value="false"/> <property name="decisionVoters"> <list> <bean class="org.acegisecurity.vote.RoleVoter"/> </list> </property> </bean> <bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices"> <property name="userDetailsService" ref="userDao"/> <property name="key" value="23_*!cdU='612./e;NrI"/> <property name="parameter" value="rememberMe"/> </bean> <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"> <property name="providers"> <list> <ref local="daoAuthenticationProvider"/> <ref local="anonymousAuthenticationProvider"/> <ref local="rememberMeAuthenticationProvider"/> </list> </property> </bean> <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"> <property name="userDetailsService" ref="userDao"/> <property name="passwordEncoder" ref="passwordEncoder"/> </bean> <bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider"> <property name="key" value="anonymous"/> </bean> <bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider"> <property name="key" value="23_*!cdU='612./e;NrI"/> </bean> <!-- This bean definition must be available to ApplicationContext.getBean() so StartupListener can look for it and detect if password encryption is turned on or not --> <bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.ShaPasswordEncoder"/> <!-- This bean is optional; it isn't used by any other bean as it only listens and logs --> <bean id="loggerListener" class="org.acegisecurity.event.authentication.LoggerListener"/> <!-- Apply method-level interceptor to userManager bean --> <aop:config> <aop:advisor id="managerSecurity" advice-ref="methodSecurityInterceptor" pointcut="execution(* org.appfuse.service.UserManager.*(..))"/> </aop:config> <bean id="methodSecurityInterceptor" class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor"> <property name="authenticationManager" ref="authenticationManager"/> <property name="accessDecisionManager" ref="accessDecisionManager"/> <property name="objectDefinitionSource"> <value> org.appfuse.service.UserManager.getUsers=ROLE_ADMIN org.appfuse.service.UserManager.removeUser=ROLE_ADMIN </value> </property> </bean> <!-- SSL Switching: to use this, configure it in the filterChainProxy bean --> <bean id="channelProcessingFilter" class="org.acegisecurity.securechannel.ChannelProcessingFilter"> <property name="channelDecisionManager" ref="channelDecisionManager"/> <property name="filterInvocationDefinitionSource"> <value> PATTERN_TYPE_APACHE_ANT /admin/**=REQUIRES_SECURE_CHANNEL /login*=REQUIRES_SECURE_CHANNEL /j_security_check*=REQUIRES_SECURE_CHANNEL /editProfile.html*=REQUIRES_SECURE_CHANNEL /signup.html*=REQUIRES_SECURE_CHANNEL /saveUser.html*=REQUIRES_SECURE_CHANNEL /**=REQUIRES_INSECURE_CHANNEL </value> </property> </bean> <bean id="channelDecisionManager" class="org.acegisecurity.securechannel.ChannelDecisionManagerImpl"> <property name="channelProcessors"> <list> <bean class="org.acegisecurity.securechannel.SecureChannelProcessor"/> <bean class="org.acegisecurity.securechannel.InsecureChannelProcessor"/> </list> </property> </bean>
</beans>
login.jsp:
<%@ include file="/common/taglibs.jsp"%>
<%@ page
import="javax.servlet.http.Cookie,org.apache.commons.codec.binary.Base64,org.springframework.util.StringUtils"%>
<script type="text/javascript" src="js/prototype/prototype-1.5.1.cr3.js"></script>
<script type="text/javascript"
src="js/scriptaculous/scriptaculous.js?load=effects"></script>
<%
response.addHeader("Pragma", "No-cache");
response.addHeader("Cache-Control", "no-cache");
response.addDateHeader("Expires", 1);
%>
<%
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if("ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE".equals(cookies[i].getName())){
String cookieValue = cookies[i].getValue();
if (Base64.isArrayByteBase64(cookieValue.getBytes())) {
String cookieAsPlainText = new String(Base64.decodeBase64(cookieValue.getBytes()));
String[] cookieTokens = StringUtils.delimitedListToStringArray(cookieAsPlainText, ":");
if (cookieTokens.length == 3) {
request.getSession().setAttribute("j_username",cookieTokens[0]);
}
}
}
}
}
%>
<html>
<head>
<title><fmt:message key="login.title" /></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
.welcometable {
margin-top: 32px;
margin-bottom: 56px;
}
#loginForm .commonsform {
padding: 16px;
}
#loginForm p {
margin-top: 10%;
margin-bottom: 8%;
margin-left:16px;
margin-right:5%;
}
#loginForm label {
font-weight: bold;
}
#loginForm input {
font-weight: normal;
color: #042B3F;
}
#loginButton {
font-size: 20px;
width: 80%;
}
#j_username {
font-size: 20px;
margin-right: 6px;
padding: 3px;
width: 97%;
}
#j_password {
font-size: 20px;
margin-right: 6px;
padding: 3px;
width: 97%;
}
</style>
</head>
<script>
function setLoginButtonState() {
if ($("j_username").value && $("j_password").value) {
$("loginButton").disabled = false;
} else {
$("loginButton").disabled = true;
}
}
function init() {
// set initial focus
if (!$("j_username").value) {
$("j_username").focus();
} else if (!$("j_password").value) {
$("j_password").focus();
} else {
$("loginButton").focus();
}
setLoginButtonState();
// observe username and password field state
// so that login button is disbaled if not both are entered.
$("j_username").observe("keydown", setLoginButtonState);
$("j_username").observe("keypress", setLoginButtonState);
$("j_username").observe("keyup", setLoginButtonState);
$("j_username").observe("change", setLoginButtonState);
$("j_password").observe("keydown", setLoginButtonState);
$("j_password").observe("keypress", setLoginButtonState);
$("j_password").observe("keyup", setLoginButtonState);
$("j_password").observe("change", setLoginButtonState);
}
Event.observe(window, "load", init);
</script>
<script>
function fieldValidation() {
var errorMessage = "";
var form = $("loginForm");
var usernameFild = $("j_username");
var passwordField = $("j_password");
if(usernameFild.value == "") {
errorMessage += "You must enter the username.\n";
}
if(usernameFild.value != ""){
if(!validateEmail(usernameFild.value)){
errorMessage += "You input login email invalid!"
}
}
if(passwordField.value == "") {
errorMessage += "You must enter the password.\n";
}
if(errorMessage == "") {
return true;
} else {
Ext.MessageBox.alert("Login fail", errorMessage);
return false;
}
}
function validateEmail(sText){
var reEmail = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
return reEmail.test(sText);
}
function toPassword(){
var test = "";
var email = $("j_username").value;
var tourl = "<%= request.getContextPath() %>/user/toPassword.action?email=";
var toPassword = test+tourl+email;
location.href = toPassword;
}
</script>
<body>
<table width="100%" cellspacing="0" cellpadding="0" border="0"
class="welcometable">
<tr>
<td align="center" valign="middle">
<div style="text-align:left;width:329px">
<c:if test="${param.error != null}">
<div class="error">
<fmt:message key="errors.password.mismatch" />
</div>
</c:if>
<form action="j_acegi_security_check" method="POST" id="loginForm"
οnsubmit="return fieldValidation();">
<table class="commonsform"
style="width: 95%; background-color: #EAF1F9">
<tr>
<td>
<p><label> <fmt:message key="login.email" /><span
class="mustfill">*</span> <br>
<input size="25" type='text' name='j_username' id="j_username"
value="<c:out value="<%=request.getSession().getAttribute("j_username") %>"/>" />
</label></p>
<p><label> <fmt:message key="login.password" /><span
class="mustfill">*</span> <br>
<input size="25" type='password' name='j_password' id="j_password">
</label></p>
<p>
<input type="checkbox" name="rememberMe" checked="checked" />
<fmt:message key="login.remember.me"/>
</p>
<p align="center"><input name="button" type="submit"
id="loginButton" value="<fmt:message key='button.login'/>"
οnclick="fieldValidation()" /></p>
</td>
</tr>
</table>
</form>
<p style="margin-left:16px;margin-right:16px">
<a href="#" οnclick="toPassword();" id="to"><fmt:message key="login.forget.password"/></a>
</p>
</div>
</td>
</tr>
</table>
</body>
</html>