KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > dinamica > security > SecurityFilter


1 package dinamica.security;
2
3 import java.io.*;
4 import javax.servlet.*;
5 import javax.servlet.http.*;
6 import dinamica.*;
7
8 import javax.sql.DataSource JavaDoc;
9 import java.sql.*;
10 import java.util.HashMap JavaDoc;
11
12 /**
13  * Servlet Filter to enforce Dinamica
14  * server-side security. This module
15  * checks/enforce authentication and autorization
16  * over protected resources, requires special configuration
17  * via filter parameters and the existence of a database schema
18  * containing the tables defined by Dinamica framework for
19  * the security system. It also assumes the existence of
20  * a set of generic Actions used for security tasks (login, loginerror, etc).
21  * This filter mantains API level compatibity with Servlet J2EE
22  * security methods, like getUserName, isUserInRole, etc.
23  *
24  * <br>
25  * Creation date: 10/march/2004<br>
26  * Last Update: 10/march/2004<br>
27  * (c) 2003 Martin Cordova<br>
28  * This code is released under the LGPL license<br>
29  * @author Martin Cordova - dinamica@martincordova.com
30  *
31  */

32
33 public class SecurityFilter implements Filter
34 {
35
36     //filter configuration object
37
private FilterConfig _config = null;
38
39     //filter parameters
40
String JavaDoc _dataSource = null;
41     String JavaDoc _ssl = null;
42     String JavaDoc _loginForm = null;
43     DataSource JavaDoc _ds = null;
44     String JavaDoc _appAlias = null;
45     String JavaDoc _passwordPolicy = null;
46     String JavaDoc _debug = null;
47     
48     //cache to store protected services and its authorized roles
49
HashMap JavaDoc protectedRes = new HashMap JavaDoc();
50
51     /**
52     * Init filter
53     **/

54     public void init(FilterConfig config) throws ServletException
55     {
56
57         _config = config;
58
59         try
60         {
61         
62             //get filter config parameters
63
_dataSource = _config.getInitParameter("datasource");
64             _loginForm = _config.getInitParameter("loginform");
65             _ssl = _config.getInitParameter("ssl");
66             _appAlias = _config.getInitParameter("app-alias");
67             _debug = _config.getInitParameter("debug");
68     
69             if (_debug==null)
70                 _debug="false";
71             
72             // get prefix for jndi lookups
73
String JavaDoc _jndiPrefix = config.getServletContext().getInitParameter("jndi-prefix");
74             if (_jndiPrefix==null)
75                 _jndiPrefix = "";
76
77             String JavaDoc jndiName = _jndiPrefix + _dataSource;
78             
79             //get filter datasource
80
_ds = Jndi.getDataSource(jndiName);
81             
82             //init security cache (protected resources)
83
loadProtectedResources();
84             
85             //save datasource JNDI name as a context attribute
86
//to be used by other modules
87
_config.getServletContext().setAttribute("dinamica.security.datasource", jndiName);
88             
89             String JavaDoc context = _config.getServletContext().getServletContextName();
90             System.err.println("FILTER STARTED [" + context + "@SecurityFilter@" + new java.util.Date JavaDoc() + "]");
91
92         }
93         catch (Throwable JavaDoc e)
94         {
95             System.err.println("[SecurityFilterException@" + new java.util.Date JavaDoc() + "] " + e.getMessage());
96             throw new ServletException(e);
97         }
98
99     }
100
101
102     /**
103     * Intercept request
104     */

105     public void doFilter (
106                             ServletRequest request,
107                             ServletResponse response,
108                             FilterChain next
109                          )
110     throws IOException, ServletException
111
112     {
113
114         //flag used to indicate if the request can proceed
115
boolean isOK = false;
116
117         //get http request/response
118
HttpServletRequest req = (HttpServletRequest) request;
119         HttpServletResponse res = (HttpServletResponse)response;
120                 
121         //get path
122
String JavaDoc uri = req.getRequestURI();
123         String JavaDoc context = _config.getServletContext().getServletContextName();
124         uri = uri.substring(context.length());
125
126         //get authenticated principal
127
HttpSession s = req.getSession(true);
128         DinamicaUser user = (DinamicaUser)s.getAttribute("dinamica.security.login");
129         
130         //create request wrapper
131
RequestWrapper rw = new RequestWrapper(req);
132         rw.setUserPrincipal(user);
133
134         //set default attributes related to security settings
135
rw.setAttribute("dinamica.security.application", _appAlias);
136         rw.setAttribute("dinamica.security.passpolicy", _passwordPolicy);
137
138         //requires SSL?
139
if (_ssl.equals("true") && !req.isSecure())
140         {
141             //not an ssl request - reject it
142
res.sendError(401,"Requires secure (HTTPS) access.");
143             return;
144         }
145
146         try
147         {
148
149             //is protected?
150
if (protectedRes.containsKey(uri))
151             {
152
153                 //get authorized roles
154
String JavaDoc roles[] = (String JavaDoc[])protectedRes.get(uri);
155
156                 //authenticated? can't access protected
157
//resource without proper authentication
158
if (user==null)
159                 {
160                     //redirect to login page
161
String JavaDoc loginPage = context + _loginForm;
162                     res.sendRedirect(loginPage);
163                 }
164                 else
165                 {
166
167                     //2005-06-09 - debug to stderr
168
if ( _debug.equals("true") )
169                     {
170                         debug(uri, roles, user);
171                     }
172                     
173                     //authorized?
174
for (int i=0; i<roles.length; i++)
175                     {
176                         //check user roles
177
if (rw.isUserInRole(roles[i]))
178                         {
179                             //OK - authorized
180
isOK = true;
181                             break;
182                         }
183                     }
184                 }
185                 
186             }
187             else
188             {
189                 //not a protected resource - let it pass
190
isOK = true;
191             }
192             
193             if (isOK)
194                 next.doFilter(rw, response);
195             else
196                 res.sendError(403,"NOT AUTHORIZED");
197
198         }
199
200         catch (Throwable JavaDoc e)
201         {
202             throw new ServletException(e);
203         }
204
205     }
206
207     /**
208      * Load into cache the list of protected
209      * resources and authorized roles for each resource
210      * @throws Throwable
211      */

212     void loadProtectedResources() throws Throwable JavaDoc
213     {
214
215         Connection con = null;
216         try
217         {
218             con = _ds.getConnection();
219             Db db = new Db(con);
220             
221             //get default password expiration policy for this webapp
222
String JavaDoc sqlpass = "select pwd_policy from s_application where app_alias = '" + _appAlias + "'";
223             Recordset rspass = db.get(sqlpass);
224             
225             if (rspass.getRecordCount()==0)
226                 throw new Throwable JavaDoc("Security configuration not found for this application alias: " + _appAlias + " - please check your web.xml configuration regarding the security filter.");
227             
228             rspass.next();
229             _passwordPolicy = rspass.getString("pwd_policy");
230             
231             //get list of protected resource for this app-alias
232
String JavaDoc sql = "select service_id, path"
233             + " from s_service s, s_application a"
234             + " where s.app_id = a.app_id"
235             + " and a.app_alias = '" + _appAlias + "'";
236             
237             Recordset rs = db.get(sql);
238                     
239             //get authorized roles for each resource
240
String JavaDoc query = "select r.rolename from"
241                             + " s_service_role sr, s_role r"
242                             + " where sr.role_id = r.role_id"
243                             + " and sr.service_id = ";
244                                         
245             while (rs.next())
246             {
247
248                 sql = query + rs.getString("service_id");
249                 
250                 Recordset rs2 = db.get(sql);
251                 
252                 //store rolenames into array
253
String JavaDoc roles[] = new String JavaDoc[rs2.getRecordCount()];
254                 int i = 0;
255                 while (rs2.next())
256                 {
257                     roles[i] = rs2.getString("rolename");
258                     i++;
259                 }
260                 
261                 //save resource + roles array into hashmap
262
protectedRes.put(rs.getString("path"), roles);
263             
264             }
265         }
266         catch (Throwable JavaDoc error)
267         {
268             throw error;
269         }
270         finally
271         {
272             if (con!=null) con.close();
273         }
274         
275     }
276
277     /* (non-Javadoc)
278      * @see javax.servlet.Filter#destroy()
279      */

280     public void destroy()
281     {
282         
283         _config = null;
284
285     }
286
287     /**
288      * Print debug information to stderr about resource access authorization
289      * @param uri Action being checked for authorization
290      * @param uriRoles Autorized roles
291      * @param user Current authenticated user
292      */

293     void debug(String JavaDoc uri, String JavaDoc[] uriRoles, DinamicaUser user)
294     {
295         try
296         {
297             String JavaDoc date = StringUtil.formatDate(new java.util.Date JavaDoc(), "yyyy-MM-dd HH:mm:ss");
298             StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
299             buf.append("[DEBUG@SecurityFilter@" + date + "] ");
300             buf.append("URI (" + uri + ") ");
301             buf.append("Authorized Roles (");
302             for (int i=0; i<uriRoles.length; i++)
303             {
304                 buf.append(uriRoles[i]+";");
305             }
306             buf.append(") ");
307             buf.append("USER (" + user.getName() + ") ");
308             buf.append("User Roles (");
309             String JavaDoc userRoles[] = user.getRoles();
310             for (int i=0; i<userRoles.length; i++)
311             {
312                 buf.append(userRoles[i]+";");
313             }
314             buf.append(") ");
315             
316             System.err.println(buf.toString());
317             
318         }
319         catch (Throwable JavaDoc e)
320         {
321             e.printStackTrace();
322         }
323     }
324     
325 }
Popular Tags