package com.phoenix.demoweb.util.web.interceptor;
import java.io.IOException;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.Authentication;
import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.event.authorization.AuthorizationFailureEvent;
import org.acegisecurity.event.authorization.AuthorizedEvent;
import org.acegisecurity.intercept.AbstractSecurityInterceptor;
import org.acegisecurity.intercept.InterceptorStatusToken;
import org.acegisecurity.intercept.ObjectDefinitionSource;
import org.acegisecurity.intercept.web.FilterInvocation;
import org.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
import com.phoenix.demoweb.module.security.service.AuthenticationService;
public class FilterSecurityInterceptor extends AbstractSecurityInterceptor
implements Filter {
private AuthenticationService authenticationService;
private static final String FILTER_APPLIED = "__acegi_filterSecurityInterceptor_filterApplied";
private ServletContext application;
private FilterInvocationDefinitionSource objectDefinitionSource;
private boolean observeOncePerRequest = true;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
String userName = null;
HttpSession session = ((HttpServletRequest) request).getSession(true);
application = session.getServletContext();
userName = (String) application.getAttribute(session.getId());
List menuList = (List) application.getAttribute("menuList");
if (menuList == null) {
menuList = this.getAuthenticationService().getMenus();
application.setAttribute("menuList", this.getAuthenticationService().getMenus());
}
if (userName != null) {
// 在portal server中不需要检查密码。故传密码null
Authentication au = this.getAuthenticationService().attemptAuthentication(
((HttpServletRequest) request), userName,null);
session.setAttribute("userName", userName);
SecurityContextHolder.getContext().setAuthentication(au);
application.removeAttribute(session.getId());
}
FilterInvocation fi = new FilterInvocation(request, response, chain);
invoke(fi);
}
public void invoke(FilterInvocation fi) throws IOException,
ServletException {
if ((fi.getRequest() != null)
&& (fi.getRequest().getAttribute(FILTER_APPLIED) != null)
&& observeOncePerRequest) {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} else {
if (fi.getRequest() != null) {
fi.getRequest().setAttribute(FILTER_APPLIED, Boolean.TRUE);
}
InterceptorStatusToken token = this.beforeInvocation(fi);
try {
fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
} finally {
super.afterInvocation(token, null);
}
}
}
protected InterceptorStatusToken beforeInvocation(Object object) {
/**
* put the role and url into ConfigAttributeDefinition Attribute
*/
FilterInvocation filterInvocation = (FilterInvocation) object;
ServletRequest request = filterInvocation.getRequest();
HttpSession session = ((HttpServletRequest) request).getSession(true);
application = session.getServletContext();
List menuList = (List) application.getAttribute("menuList");
ConfigAttributeDefinition attr = null;
attr = this.getAuthenticationService().getAcegiConfig(object, menuList);
if (attr == null) {
return null; // no further work post-invocation
}
Authentication authenticated = null;
if (!SecurityContextHolder.getContext().getAuthentication()
.isAuthenticated()
|| super.isAlwaysReauthenticate()) {
try {
authenticated = super.getAuthenticationManager().authenticate(
SecurityContextHolder.getContext().getAuthentication());
} catch (Exception e) {
e.printStackTrace();
}
SecurityContextHolder.getContext().setAuthentication(authenticated);
} else {
authenticated = SecurityContextHolder.getContext()
.getAuthentication();
}
try {
super.getAccessDecisionManager()
.decide(authenticated, object, attr);
} catch (AccessDeniedException accessDeniedException) {
AuthorizationFailureEvent event = new AuthorizationFailureEvent(
object, attr, authenticated, accessDeniedException);
throw accessDeniedException;
}
AuthorizedEvent event = new AuthorizedEvent(object, attr, authenticated);
Authentication runAs = this.getRunAsManager().buildRunAs(authenticated,
object, attr);
if (runAs == null) {
return new InterceptorStatusToken(authenticated, false, attr,
object);
} else {
SecurityContextHolder.getContext().setAuthentication(runAs);
return new InterceptorStatusToken(authenticated, true, attr, object);
}
}
public FilterInvocationDefinitionSource getObjectDefinitionSource() {
return this.objectDefinitionSource;
}
public Class getSecureObjectClass() {
return FilterInvocation.class;
}
/**
* Not used (we rely on IoC container lifecycle services instead)
*
* @param arg0
* ignored
*
* @throws ServletException
* never thrown
*/
public void init(FilterConfig araeg0) throws ServletException {
}
/**
* Indicates whether once-per-request handling will be observed. By default
* this is <code>true</code>, meaning the
* <code>FilterSecurityInterceptor</code> will only execute
* once-per-request. Sometimes users may wish it to execute more than once
* per request, such as when JSP forwards are being used and filter security
* is desired on each included fragment of the HTTP request.
*
* @return <code>true</code> (the default) if once-per-request is
* honoured, otherwise <code>false</code> if
* <code>FilterSecurityInterceptor</code> will enforce
* authorizations for each and every fragment of the HTTP request.
*/
public boolean isObserveOncePerRequest() {
return observeOncePerRequest;
}
public ObjectDefinitionSource obtainObjectDefinitionSource() {
return this.objectDefinitionSource;
}
public void setObjectDefinitionSource(
FilterInvocationDefinitionSource newSource) {
this.objectDefinitionSource = newSource;
}
public void setObserveOncePerRequest(boolean observeOncePerRequest) {
this.observeOncePerRequest = observeOncePerRequest;
}
public AuthenticationService getAuthenticationService() {
return authenticationService;
}
public void setAuthenticationService(AuthenticationService authenticationService) {
this.authenticationService = authenticationService;
}
}