1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.ui.basicauth;
17
18 import java.io.IOException;
19
20 import javax.servlet.Filter;
21 import javax.servlet.FilterChain;
22 import javax.servlet.FilterConfig;
23 import javax.servlet.ServletException;
24 import javax.servlet.ServletRequest;
25 import javax.servlet.ServletResponse;
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpServletResponse;
28
29 import org.acegisecurity.Authentication;
30 import org.acegisecurity.AuthenticationException;
31 import org.acegisecurity.AuthenticationManager;
32 import org.acegisecurity.context.SecurityContextHolder;
33 import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
34 import org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken;
35 import org.acegisecurity.ui.AuthenticationDetailsSource;
36 import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
37 import org.acegisecurity.ui.AuthenticationEntryPoint;
38 import org.acegisecurity.ui.rememberme.RememberMeServices;
39 import org.apache.commons.codec.binary.Base64;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.springframework.beans.factory.InitializingBean;
43 import org.springframework.util.Assert;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 public class BasicProcessingFilter implements Filter, InitializingBean {
77
78
79 private static final Log logger = LogFactory.getLog(BasicProcessingFilter.class);
80
81
82
83 private AuthenticationDetailsSource authenticationDetailsSource = new AuthenticationDetailsSourceImpl();
84 private AuthenticationEntryPoint authenticationEntryPoint;
85 private AuthenticationManager authenticationManager;
86 private RememberMeServices rememberMeServices;
87 private boolean ignoreFailure = false;
88
89
90
91 public void afterPropertiesSet() throws Exception {
92 Assert.notNull(this.authenticationManager, "An AuthenticationManager is required");
93 Assert.notNull(this.authenticationEntryPoint, "An AuthenticationEntryPoint is required");
94 }
95
96 public void destroy() {}
97
98 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
99 throws IOException, ServletException {
100
101 if (!(request instanceof HttpServletRequest)) {
102 throw new ServletException("Can only process HttpServletRequest");
103 }
104
105 if (!(response instanceof HttpServletResponse)) {
106 throw new ServletException("Can only process HttpServletResponse");
107 }
108
109 HttpServletRequest httpRequest = (HttpServletRequest) request;
110 HttpServletResponse httpResponse = (HttpServletResponse) response;
111
112 String header = httpRequest.getHeader("Authorization");
113
114 if (logger.isDebugEnabled()) {
115 logger.debug("Authorization header: " + header);
116 }
117
118 if ((header != null) && header.startsWith("Basic ")) {
119 String base64Token = header.substring(6);
120 String token = new String(Base64.decodeBase64(base64Token.getBytes()));
121
122 String username = "";
123 String password = "";
124 int delim = token.indexOf(":");
125
126 if (delim != -1) {
127 username = token.substring(0, delim);
128 password = token.substring(delim + 1);
129 }
130
131 if (authenticationIsRequired(username)) {
132 UsernamePasswordAuthenticationToken authRequest =
133 new UsernamePasswordAuthenticationToken(username, password);
134 authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request));
135
136 Authentication authResult;
137
138 try {
139 authResult = authenticationManager.authenticate(authRequest);
140 } catch (AuthenticationException failed) {
141
142 if (logger.isDebugEnabled()) {
143 logger.debug("Authentication request for user: " + username + " failed: " + failed.toString());
144 }
145
146 SecurityContextHolder.getContext().setAuthentication(null);
147
148 if (rememberMeServices != null) {
149 rememberMeServices.loginFail(httpRequest, httpResponse);
150 }
151
152 if (ignoreFailure) {
153 chain.doFilter(request, response);
154 } else {
155 authenticationEntryPoint.commence(request, response, failed);
156 }
157
158 return;
159 }
160
161
162 if (logger.isDebugEnabled()) {
163 logger.debug("Authentication success: " + authResult.toString());
164 }
165
166 SecurityContextHolder.getContext().setAuthentication(authResult);
167
168 if (rememberMeServices != null) {
169 rememberMeServices.loginSuccess(httpRequest, httpResponse, authResult);
170 }
171 }
172 }
173
174 chain.doFilter(request, response);
175 }
176
177 private boolean authenticationIsRequired(String username) {
178
179
180 Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
181
182 if(existingAuth == null || !existingAuth.isAuthenticated()) {
183 return true;
184 }
185
186
187
188
189 if (existingAuth instanceof UsernamePasswordAuthenticationToken && !existingAuth.getName().equals(username)) {
190 return true;
191 }
192
193
194
195
196
197
198
199
200 if (existingAuth instanceof AnonymousAuthenticationToken) {
201 return true;
202 }
203
204 return false;
205 }
206
207 public AuthenticationEntryPoint getAuthenticationEntryPoint() {
208 return authenticationEntryPoint;
209 }
210
211 public AuthenticationManager getAuthenticationManager() {
212 return authenticationManager;
213 }
214
215 public void init(FilterConfig arg0) throws ServletException {}
216
217 public boolean isIgnoreFailure() {
218 return ignoreFailure;
219 }
220
221 public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) {
222 Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
223 this.authenticationDetailsSource = authenticationDetailsSource;
224 }
225
226 public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) {
227 this.authenticationEntryPoint = authenticationEntryPoint;
228 }
229
230 public void setAuthenticationManager(AuthenticationManager authenticationManager) {
231 this.authenticationManager = authenticationManager;
232 }
233
234 public void setIgnoreFailure(boolean ignoreFailure) {
235 this.ignoreFailure = ignoreFailure;
236 }
237
238 public void setRememberMeServices(RememberMeServices rememberMeServices) {
239 this.rememberMeServices = rememberMeServices;
240 }
241
242 }