1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.ui.rememberme;
17
18 import org.acegisecurity.context.SecurityContextHolder;
19 import org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent;
20 import org.acegisecurity.Authentication;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 import org.springframework.beans.factory.InitializingBean;
26
27 import org.springframework.context.ApplicationEventPublisher;
28 import org.springframework.context.ApplicationEventPublisherAware;
29
30 import org.springframework.util.Assert;
31
32 import java.io.IOException;
33
34 import javax.servlet.Filter;
35 import javax.servlet.FilterChain;
36 import javax.servlet.FilterConfig;
37 import javax.servlet.ServletException;
38 import javax.servlet.ServletRequest;
39 import javax.servlet.ServletResponse;
40 import javax.servlet.http.HttpServletRequest;
41 import javax.servlet.http.HttpServletResponse;
42
43
44 /***
45 * Detects if there is no <code>Authentication</code> object in the
46 * <code>SecurityContext</code>, and populates it with a remember-me
47 * authentication token if a {@link
48 * org.acegisecurity.ui.rememberme.RememberMeServices} implementation so
49 * requests.
50 *
51 * <p>
52 * Concrete <code>RememberMeServices</code> implementations will have their
53 * {@link
54 * org.acegisecurity.ui.rememberme.RememberMeServices#autoLogin(HttpServletRequest,
55 * HttpServletResponse)} method called by this filter. The
56 * <code>Authentication</code> or <code>null</code> returned by that method
57 * will be placed into the <code>SecurityContext</code>.
58 * </p>
59 *
60 * <p>
61 * If authentication is successful, an {@link
62 * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} will be
63 * published to the application context. No events will be published if
64 * authentication was unsuccessful, because this would generally be recorded
65 * via an <code>AuthenticationManager</code>-specific application event.
66 * </p>
67 *
68 * <p>
69 * <b>Do not use this class directly.</b> Instead configure
70 * <code>web.xml</code> to use the {@link
71 * org.acegisecurity.util.FilterToBeanProxy}.
72 * </p>
73 *
74 * @author Ben Alex
75 * @version $Id: RememberMeProcessingFilter.java,v 1.10 2005/11/17 00:56:09 benalex Exp $
76 */
77 public class RememberMeProcessingFilter implements Filter, InitializingBean,
78 ApplicationEventPublisherAware {
79
80
81 private static final Log logger = LogFactory.getLog(RememberMeProcessingFilter.class);
82
83
84
85 private ApplicationEventPublisher eventPublisher;
86 private RememberMeServices rememberMeServices = new NullRememberMeServices();
87
88
89
90 public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
91 this.eventPublisher = eventPublisher;
92 }
93
94 public void setRememberMeServices(RememberMeServices rememberMeServices) {
95 this.rememberMeServices = rememberMeServices;
96 }
97
98 public RememberMeServices getRememberMeServices() {
99 return rememberMeServices;
100 }
101
102 public void afterPropertiesSet() throws Exception {
103 Assert.notNull(rememberMeServices);
104 }
105
106 /***
107 * Does nothing - we rely on IoC lifecycle services instead.
108 */
109 public void destroy() {}
110
111 public void doFilter(ServletRequest request, ServletResponse response,
112 FilterChain chain) throws IOException, ServletException {
113 if (!(request instanceof HttpServletRequest)) {
114 throw new ServletException("Can only process HttpServletRequest");
115 }
116
117 if (!(response instanceof HttpServletResponse)) {
118 throw new ServletException("Can only process HttpServletResponse");
119 }
120
121 HttpServletRequest httpRequest = (HttpServletRequest) request;
122 HttpServletResponse httpResponse = (HttpServletResponse) response;
123
124 if (SecurityContextHolder.getContext().getAuthentication() == null) {
125 Authentication rememberMeAuth =
126 rememberMeServices.autoLogin(httpRequest, httpResponse);
127
128 if(rememberMeAuth != null) {
129 SecurityContextHolder.getContext().setAuthentication(rememberMeAuth);
130
131 if (logger.isDebugEnabled()) {
132 logger.debug(
133 "SecurityContextHolder populated with remember-me token: '"
134 + SecurityContextHolder.getContext().getAuthentication()
135 + "'");
136 }
137
138
139 if (this.eventPublisher != null) {
140 eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
141 SecurityContextHolder.getContext().getAuthentication(),
142 this.getClass()));
143 }
144 }
145 } else {
146 if (logger.isDebugEnabled()) {
147 logger.debug(
148 "SecurityContextHolder not populated with remember-me token, as it already contained: '"
149 + SecurityContextHolder.getContext().getAuthentication()
150 + "'");
151 }
152 }
153
154 chain.doFilter(request, response);
155 }
156
157 /***
158 * Does nothing - we rely on IoC lifecycle services instead.
159 *
160 * @param ignored not used
161 *
162 */
163 public void init(FilterConfig ignored) throws ServletException {}
164 }