KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > atlassian > seraph > filter > SecurityFilter


1 package com.atlassian.seraph.filter;
2
3 import org.apache.log4j.Category;
4
5 import javax.servlet.*;
6 import javax.servlet.http.HttpServletRequest JavaDoc;
7 import javax.servlet.http.HttpServletResponse JavaDoc;
8 import java.io.IOException JavaDoc;
9 import java.util.HashSet JavaDoc;
10 import java.util.Iterator JavaDoc;
11 import java.util.Set JavaDoc;
12 import java.security.Principal JavaDoc;
13
14 import com.atlassian.seraph.config.SecurityConfig;
15 import com.atlassian.seraph.config.SecurityConfigFactory;
16 import com.atlassian.seraph.SecurityService;
17 import com.atlassian.seraph.auth.AuthenticationContext;
18 import com.atlassian.seraph.util.RedirectUtils;
19
20 /**
21  * The SecurityFilter determines which roles are required for a given request by querying all of the Services.
22  *
23  * @see SecurityService
24  */

25 public class SecurityFilter implements Filter
26 {
27     private FilterConfig config = null;
28     private SecurityConfig securityConfig = null;
29
30     private static final Category log = Category.getInstance(SecurityFilter.class);
31     private static final String JavaDoc ALREADY_FILTERED = "os_securityfilter_already_filtered";
32     public static final String JavaDoc ORIGINAL_URL = "atlassian.core.seraph.original.url";
33
34     public void init(FilterConfig config)
35     {
36         // log.debug("SecurityFilter.init");
37
this.config = config;
38
39         String JavaDoc configFileLocation = null;
40
41         if (config.getInitParameter("config.file") != null)
42         {
43             configFileLocation = config.getInitParameter("config.file");
44             log.debug("Security config file location: " + configFileLocation);
45         }
46
47         securityConfig = SecurityConfigFactory.getInstance(configFileLocation);
48         config.getServletContext().setAttribute(SecurityConfig.STORAGE_KEY, securityConfig);
49     }
50
51     public void destroy()
52     {
53         // log.debug("SecurityFilter.destroy");
54
securityConfig.destroy();
55         securityConfig = null;
56         config = null;
57     }
58
59     /**
60      * @deprecated Not needed in latest version of Servlet 2.3 API
61      */

62     // NOTE: Filter doesn't work with Orion 1.5.2 without this method
63
public FilterConfig getFilterConfig()
64     {
65         return config;
66     }
67
68     /**
69      * @deprecated Not needed in latest version of Servlet 2.3 API - replaced by init().
70      */

71     // NOTE: Filter doesn't work with Orion 1.5.2 without this method
72
public void setFilterConfig(FilterConfig filterConfig)
73     {
74         if (filterConfig != null) //it seems that Orion 1.5.2 calls this with a null config.
75
init(filterConfig);
76     }
77
78     public void doFilter(ServletRequest JavaDoc req, ServletResponse JavaDoc res, FilterChain chain)
79             throws IOException JavaDoc, ServletException
80     {
81         if (req.getAttribute(ALREADY_FILTERED) != null || !getSecurityConfig().getController().isSecurityEnabled())
82         {
83             chain.doFilter(req, res);
84             return;
85         }
86         else
87         {
88             req.setAttribute(ALREADY_FILTERED, Boolean.TRUE);
89         }
90
91         // Try and get around Orion's bug when redeploying
92
// it seems that filters are not called in the correct order
93
if (req.getAttribute(LoginFilter.ALREADY_FILTERED) == null)
94         {
95             log.warn("LoginFilter not yet applied to this request - terminating filter chain");
96             return;
97         }
98
99         HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) req;
100         HttpServletResponse JavaDoc response = (HttpServletResponse JavaDoc) res;
101
102         String JavaDoc originalURL = request.getServletPath() +
103                 (request.getPathInfo() == null ? "" : request.getPathInfo()) +
104                 (request.getQueryString() == null ? "" : "?" + request.getQueryString());
105
106
107         // store the original URL as a request attribute anyway - often useful for pages to access it (ie login links)
108
request.setAttribute(SecurityFilter.ORIGINAL_URL, originalURL);
109
110         Set JavaDoc requiredRoles = new HashSet JavaDoc();
111
112         // loop through loaded services and get required roles
113
for (Iterator JavaDoc iterator = getSecurityConfig().getServices().iterator(); iterator.hasNext();)
114         {
115             SecurityService service = (SecurityService) iterator.next();
116
117             Set JavaDoc serviceRoles = service.getRequiredRoles(request);
118             requiredRoles.addAll(serviceRoles);
119         }
120
121         if (log.isDebugEnabled()) {
122             log.debug("requiredRoles = " + requiredRoles);
123         }
124
125         // whether this URL needs authorisation
126
boolean needAuth = false;
127
128         // try to get the user (for cookie logins)
129
Principal JavaDoc user = getSecurityConfig().getAuthenticator().getUser(request, response);
130
131         // set the user in the context
132
getAuthenticationContext().setUser(user);
133
134         // check if the current user has all required permissions
135
// if there is no current user, request.isUserInRole() always returns false so this works
136
for (Iterator JavaDoc iterator = requiredRoles.iterator(); iterator.hasNext();)
137         {
138             String JavaDoc role = (String JavaDoc) iterator.next();
139
140             // this isUserInRole method is only used here and 'd be better off replaced by getRoleMapper().hasRole(user, request, role)) since we have the user already
141
// was : if (!securityConfig.getAuthenticator().isUserInRole(request, role))
142
if (!getSecurityConfig().getRoleMapper().hasRole(user, request, role))
143             {
144                 log.info("User '" + user + "' needs (and lacks) role '" + role + "' to access " + originalURL);
145                 needAuth = true;
146             }
147         }
148
149         // check if we're at the signon page, in which case do not auth
150
if (request.getServletPath() != null && request.getServletPath().equals(getSecurityConfig().getLoginURL()))
151         {
152             needAuth = false;
153         }
154
155         // if we need to authenticate, store current URL and forward
156
if (needAuth)
157         {
158             if (log.isDebugEnabled())
159                 log.debug("Need Authentication: Redirecting to: " + getSecurityConfig().getLoginURL() + " from: " + originalURL);
160             request.getSession().setAttribute(getSecurityConfig().getOriginalURLKey(), originalURL);
161             response.sendRedirect(RedirectUtils.getLoginUrl(request));
162             return;
163         }
164         else
165         {
166             try
167             {
168                 chain.doFilter(req, res);
169             }
170             finally
171             {
172                 // clear the user from the context
173
getAuthenticationContext().clearUser();
174             }
175         }
176     }
177
178     protected SecurityConfig getSecurityConfig() {
179         // ?? is this any useful, since we already initalize this in the init method ??
180
if (securityConfig == null)
181         {
182             securityConfig = (SecurityConfig) config.getServletContext().getAttribute(SecurityConfig.STORAGE_KEY);
183         }
184         return securityConfig;
185     }
186
187     protected AuthenticationContext getAuthenticationContext() {
188         return getSecurityConfig().getAuthenticationContext();
189     }
190
191 }
192
Popular Tags