1 package com.atlassian.seraph.filter;
2
3 import com.atlassian.seraph.RequestParameterConstants;
4 import com.atlassian.seraph.auth.Authenticator;
5 import com.atlassian.seraph.config.SecurityConfig;
6 import com.atlassian.seraph.config.SecurityConfigFactory;
7 import com.atlassian.seraph.util.RedirectUtils;
8 import org.apache.log4j.Logger;
9
10 import java.io.IOException;
11 import java.net.URI;
12 import java.net.URISyntaxException;
13 import java.security.Principal;
14 import javax.servlet.*;
15 import javax.servlet.http.HttpServletRequest;
16 import javax.servlet.http.HttpServletRequestWrapper;
17 import javax.servlet.http.HttpServletResponse;
18 import javax.servlet.http.HttpSession;
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public abstract class BaseLoginFilter implements Filter
42 {
43 private static final Logger log = Logger.getLogger(BaseLoginFilter.class);
44
45 private FilterConfig filterConfig = null;
46 protected static final String ALREADY_FILTERED = "loginfilter.already.filtered";
47 public static final String LOGIN_SUCCESS = "success";
48 public static final String LOGIN_FAILED = "failed";
49 public static final String LOGIN_ERROR = "error";
50 public static final String LOGIN_NOATTEMPT = null;
51 public static final String OS_AUTHSTATUS_KEY = "os_authstatus";
52 private SecurityConfig securityConfig = null;
53
54 public BaseLoginFilter()
55 {
56 super();
57 }
58
59 public void init(FilterConfig config)
60 {
61
62 this.filterConfig = config;
63 }
64
65 public void destroy()
66 {
67
68 filterConfig = null;
69 }
70
71
72
73
74 public FilterConfig getFilterConfig()
75 {
76 return filterConfig;
77 }
78
79
80
81
82 public void setFilterConfig(FilterConfig filterConfig)
83 {
84 if (filterConfig != null)
85 {
86 init(filterConfig);
87 }
88 }
89
90 public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
91 throws IOException, ServletException
92 {
93 final boolean dbg = log.isDebugEnabled();
94
95 req = new SecurityHttpRequestWrapper((HttpServletRequest) req);
96
97 if (req.getAttribute(ALREADY_FILTERED) == null && getSecurityConfig().getController().isSecurityEnabled())
98 {
99 req.setAttribute(ALREADY_FILTERED, Boolean.TRUE);
100 req.setAttribute(OS_AUTHSTATUS_KEY, LOGIN_NOATTEMPT);
101
102 HttpServletRequest request = (HttpServletRequest) req;
103 HttpServletResponse response = (HttpServletResponse) res;
104
105 if (dbg)
106 {
107 String url = request.getServletPath() +
108 (request.getPathInfo() == null ? "" : request.getPathInfo()) +
109 (request.getQueryString() == null ? "" : "?" + request.getQueryString());
110 log.debug("____ Attempting login for : '" + url + "'");
111 }
112
113 String status = login(request, response);
114 request.setAttribute(OS_AUTHSTATUS_KEY, status);
115 if (dbg)
116 {
117 log.debug("Login completed - set " + OS_AUTHSTATUS_KEY + " attribute to '" + status + "'");
118 }
119
120
121 if (status == LOGIN_SUCCESS && redirectToOriginalDestination(request, response))
122 {
123 return;
124 }
125 if(status == LOGIN_NOATTEMPT)
126 {
127 issuePossibleRedirectIfUserIsAlreadyLoggedIn(req, request, response);
128
129 }
130 }
131
132 chain.doFilter(req, res);
133 }
134
135 private void issuePossibleRedirectIfUserIsAlreadyLoggedIn(ServletRequest req, HttpServletRequest request, HttpServletResponse response)
136 throws IOException
137 {
138
139
140
141
142
143 if (request.getParameterMap().get(RequestParameterConstants.OS_DESTINATION) != null)
144 {
145 Principal principal = getAuthenticator().getUser(request);
146 if (principal != null)
147 {
148 HttpSession session = ((HttpServletRequest)req).getSession();
149 if (session != null && session.getAttribute(SecurityConfigFactory.getInstance().getOriginalURLKey()) == null)
150 {
151 redirectToOriginalDestination(request, response);
152 }
153 }
154 }
155 }
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172 public abstract String login(HttpServletRequest request, HttpServletResponse response);
173
174 private class SecurityHttpRequestWrapper extends HttpServletRequestWrapper
175 {
176 private HttpServletRequest request;
177
178 public SecurityHttpRequestWrapper(HttpServletRequest request)
179 {
180 super(request);
181 this.request = request;
182 }
183
184 public String getRemoteUser()
185 {
186 Principal user = getUserPrincipal();
187 return (user == null) ? null : user.getName();
188 }
189
190 public Principal getUserPrincipal()
191 {
192 return getSecurityConfig().getAuthenticator().getUser(request);
193 }
194 }
195
196
197
198
199
200
201
202
203
204 protected boolean redirectToOriginalDestination(HttpServletRequest request, HttpServletResponse response)
205 throws IOException
206 {
207 String originalURL = (String) request.getSession().getAttribute(getSecurityConfig().getOriginalURLKey());
208 String destinationURL = request.getParameter(RequestParameterConstants.OS_DESTINATION);
209 String redirectURL = null;
210
211 if (originalURL != null)
212 {
213 request.getSession().setAttribute(getSecurityConfig().getOriginalURLKey(), null);
214 redirectURL = originalURL;
215 }
216 else if (destinationURL != null)
217 {
218 redirectURL = destinationURL;
219 }
220
221 if (redirectURL == null)
222 {
223 return false;
224 }
225
226 if (!isAbsoluteUrl(redirectURL))
227 {
228 redirectURL = RedirectUtils.appendPathToContext(request.getContextPath(), redirectURL);
229 }
230
231 if (log.isDebugEnabled())
232 {
233 log.debug("Logged In - redirecting to: " + redirectURL);
234 }
235
236 response.sendRedirect(redirectURL);
237 return true;
238 }
239
240 protected boolean isAbsoluteUrl(String url)
241 {
242 try
243 {
244 URI uri = new URI(url);
245 return uri.isAbsolute();
246 }
247 catch (URISyntaxException e)
248 {
249 return false;
250 }
251 }
252
253 protected Authenticator getAuthenticator()
254 {
255 return getSecurityConfig().getAuthenticator();
256 }
257
258 protected SecurityConfig getSecurityConfig()
259 {
260 if (securityConfig == null)
261 {
262 securityConfig = (SecurityConfig) filterConfig.getServletContext().getAttribute(SecurityConfig.STORAGE_KEY);
263 }
264 return securityConfig;
265 }
266 }