KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > jetty6 > handler > JettySecurityHandler


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.geronimo.jetty6.handler;
18
19 import java.io.IOException JavaDoc;
20 import java.security.AccessControlContext JavaDoc;
21 import java.security.AccessControlException JavaDoc;
22 import java.security.PermissionCollection JavaDoc;
23 import java.security.Principal JavaDoc;
24
25 import javax.security.auth.Subject JavaDoc;
26 import javax.security.jacc.PolicyContext JavaDoc;
27 import javax.security.jacc.WebResourcePermission JavaDoc;
28 import javax.security.jacc.WebUserDataPermission JavaDoc;
29 import javax.servlet.ServletException JavaDoc;
30 import javax.servlet.http.HttpServletRequest JavaDoc;
31 import javax.servlet.http.HttpServletResponse JavaDoc;
32
33 import org.apache.geronimo.common.DeploymentException;
34 import org.apache.geronimo.common.GeronimoSecurityException;
35 import org.apache.geronimo.security.Callers;
36 import org.apache.geronimo.security.ContextManager;
37 import org.apache.geronimo.security.IdentificationPrincipal;
38 import org.apache.geronimo.security.SubjectId;
39 import org.apache.geronimo.security.deploy.DefaultPrincipal;
40 import org.apache.geronimo.security.util.ConfigurationUtil;
41 import org.apache.geronimo.jetty6.JAASJettyPrincipal;
42 import org.apache.geronimo.jetty6.JAASJettyRealm;
43 import org.apache.geronimo.jetty6.JettyContainer;
44 import org.mortbay.jetty.HttpException;
45 import org.mortbay.jetty.Request;
46 import org.mortbay.jetty.Response;
47 import org.mortbay.jetty.security.Authenticator;
48 import org.mortbay.jetty.security.FormAuthenticator;
49 import org.mortbay.jetty.security.SecurityHandler;
50
51 public class JettySecurityHandler extends SecurityHandler {
52
53     private String JavaDoc policyContextID;
54
55     private JAASJettyPrincipal defaultPrincipal;
56
57     private String JavaDoc formLoginPath;
58
59     private PermissionCollection JavaDoc checked;
60
61     private PermissionCollection JavaDoc excludedPermissions;
62
63
64     private JAASJettyRealm realm;
65
66     public JettySecurityHandler() {
67     }
68
69     public boolean hasConstraints() {
70         return true;
71     }
72
73     public void init(String JavaDoc policyContextID,
74             DefaultPrincipal defaultPrincipal,
75             PermissionCollection JavaDoc checkedPermissions,
76             PermissionCollection JavaDoc excludedPermissions,
77             ClassLoader JavaDoc classLoader) {
78         this.policyContextID = policyContextID;
79
80         this.defaultPrincipal = generateDefaultPrincipal(defaultPrincipal,classLoader);
81         this.checked = checkedPermissions;
82         this.excludedPermissions = excludedPermissions;
83
84         Authenticator authenticator = getAuthenticator();
85         if (authenticator instanceof FormAuthenticator) {
86             String JavaDoc formLoginPath = ((FormAuthenticator) authenticator).getLoginPage();
87             if (formLoginPath.indexOf('?') > 0) {
88                 formLoginPath = formLoginPath.substring(0, formLoginPath.indexOf('?'));
89             }
90             this.formLoginPath = formLoginPath;
91         } else {
92             formLoginPath = null;
93         }
94
95         /**
96          * Register our default principal with the ContextManager
97          */

98         Subject JavaDoc defaultSubject = this.defaultPrincipal.getSubject();
99         ContextManager.registerSubject(defaultSubject);
100         SubjectId id = ContextManager.getSubjectId(defaultSubject);
101         defaultSubject.getPrincipals().add(new IdentificationPrincipal(id));
102         this.realm = (JAASJettyRealm)getUserRealm();
103         assert realm != null;
104     }
105
106     public void doStop(JettyContainer jettyContainer) throws Exception JavaDoc {
107         try{
108             super.doStop();
109         }
110         finally {
111             Subject JavaDoc defaultSubject = this.defaultPrincipal.getSubject();
112             ContextManager.unregisterSubject(defaultSubject);
113             jettyContainer.removeRealm(realm.getSecurityRealmName());
114         }
115     }
116
117     /* ------------------------------------------------------------ */
118     /*
119      * @see org.mortbay.jetty.security.SecurityHandler#handle(java.lang.String,
120      * javax.servlet.http.HttpServletRequest,
121      * javax.servlet.http.HttpServletResponse, int)
122      */

123     public void handle(String JavaDoc target, HttpServletRequest JavaDoc request,
124             HttpServletResponse JavaDoc response, int dispatch) throws IOException JavaDoc,
125             ServletException JavaDoc {
126         String JavaDoc old_policy_id = PolicyContext.getContextID();
127         Callers oldCallers = ContextManager.getCallers();
128
129         try {
130             PolicyContext.setContextID(policyContextID);
131             PolicyContext.setHandlerData(request);
132
133             super.handle(target, request, response, dispatch);
134         } finally {
135             PolicyContext.setContextID(old_policy_id);
136             ContextManager.popCallers(oldCallers);
137         }
138     }
139
140 // public static Subject getCurrentRoleDesignate(String role) {
141
// return ((JettySecurityHandler) (WebAppContext.getCurrentWebAppContext()
142
// .getSecurityHandler())).getRoleDesignate(role);
143
// }
144
//
145
// private Subject getRoleDesignate(String roleName) {
146
// return (Subject) roleDesignates.get(roleName);
147
// }
148

149     /**
150      * Check the security constraints using JACC.
151      *
152      * @param pathInContext
153      * path in context
154      * @param request
155      * HTTP request
156      * @param response
157      * HTTP response
158      * @return true if the path in context passes the security check, false if
159      * it fails or a redirection has occured during authentication.
160      */

161     public boolean checkSecurityConstraints(String JavaDoc pathInContext,
162             Request JavaDoc request, Response JavaDoc response) throws HttpException,
163             IOException JavaDoc {
164         if (formLoginPath != null) {
165             String JavaDoc pathToBeTested = (pathInContext.indexOf('?') > 0 ? pathInContext
166                     .substring(0, pathInContext.indexOf('?'))
167                     : pathInContext);
168
169             if (pathToBeTested.equals(formLoginPath)) {
170                 return true;
171             }
172         }
173
174         try {
175             String JavaDoc transportType;
176             if (request.isSecure()) {
177                 transportType = "CONFIDENTIAL";
178             } else if (request.getConnection().isIntegral(request)) {
179                 transportType = "INTEGRAL";
180             } else {
181                 transportType = "NONE";
182             }
183             WebUserDataPermission JavaDoc wudp = new WebUserDataPermission JavaDoc(pathInContext, new String JavaDoc[] { request.getMethod() }, transportType);
184             WebResourcePermission JavaDoc webResourcePermission = new WebResourcePermission JavaDoc(request);
185             Principal JavaDoc user = obtainUser(pathInContext, request, response, webResourcePermission, wudp);
186
187             if (user == null) {
188                 return false;
189             }
190             if (user == SecurityHandler.__NOBODY) {
191                 return true;
192             }
193
194             AccessControlContext JavaDoc acc = ContextManager.getCurrentContext();
195
196             /**
197              * JACC v1.0 secion 4.1.1
198              */

199
200             acc.checkPermission(wudp);
201
202             /**
203              * JACC v1.0 secion 4.1.2
204              */

205             acc.checkPermission(webResourcePermission);
206         } catch (HttpException he) {
207             response.sendError(he.getStatus(), he.getReason());
208             return false;
209         } catch (AccessControlException JavaDoc ace) {
210             response.sendError(403);
211             return false;
212         }
213         return true;
214     }
215
216     /**
217      * Obtain an authenticated user, if one is required. Otherwise return the
218      * default principal. <p/> Also set the current caller for JACC security
219      * checks for the default principal. This is automatically done by
220      * <code>JAASJettyRealm</code>.
221      *
222      * @param pathInContext
223      * path in context
224      * @param request
225      * HTTP request
226      * @param response
227      * HTTP response
228      * @return <code>null</code> if there is no authenticated user at the
229      * moment and security checking should not proceed and servlet
230      * handling should also not proceed, e.g. redirect.
231      * <code>SecurityConstraint.__NOBODY</code> if security checking
232      * should not proceed and servlet handling should proceed, e.g.
233      * login page.
234      */

235     private Principal JavaDoc obtainUser(String JavaDoc pathInContext, Request JavaDoc request,
236             Response JavaDoc response, WebResourcePermission JavaDoc resourcePermission,
237             WebUserDataPermission JavaDoc dataPermission) throws IOException JavaDoc {
238         boolean unauthenticated = !(checked.implies(resourcePermission) || checked.implies(dataPermission));
239         boolean forbidden = excludedPermissions.implies(resourcePermission) || excludedPermissions.implies(dataPermission);
240
241         Authenticator authenticator = getAuthenticator();
242         if (!unauthenticated && !forbidden) {
243             return authenticator.authenticate(realm, pathInContext, request,
244                     response);
245         } else if (authenticator instanceof FormAuthenticator
246                 && pathInContext.endsWith(FormAuthenticator.__J_SECURITY_CHECK)) {
247             /**
248              * This could be a post request to __J_SECURITY_CHECK.
249              */

250             return authenticator.authenticate(realm, pathInContext, request,
251                     response);
252         }
253
254         // attempt to access an unprotected resource that is not the
255
// j_security_check.
256
// if we are logged in, return the logged in principal.
257
if (request != null) {
258             // null response appears to prevent redirect to login page
259
Principal JavaDoc user = authenticator.authenticate(realm, pathInContext,
260                     request, null);
261             if (user != null) {
262                 return user;
263             }
264         }
265
266         /**
267          * No authentication is required. Return the defaultPrincipal.
268          */

269         //TODO use run-as as nextCaller if present
270
ContextManager.setCallers(defaultPrincipal.getSubject(), defaultPrincipal.getSubject());
271         return defaultPrincipal;
272     }
273
274     /**
275      * Generate the default principal from the security config.
276      *
277      * @param defaultPrincipal
278      * The Geronimo security configuration.
279      * @param classLoader
280      * @return the default principal
281      */

282     protected JAASJettyPrincipal generateDefaultPrincipal(
283             DefaultPrincipal defaultPrincipal, ClassLoader JavaDoc classLoader)
284             throws GeronimoSecurityException {
285
286         if (defaultPrincipal == null) {
287             throw new GeronimoSecurityException(
288                     "Unable to generate default principal");
289         }
290
291         try {
292             JAASJettyPrincipal result = new JAASJettyPrincipal("default");
293             Subject JavaDoc defaultSubject = ConfigurationUtil.generateDefaultSubject(
294                     defaultPrincipal, classLoader);
295
296             result.setSubject(defaultSubject);
297
298             return result;
299         } catch (DeploymentException de) {
300             throw new GeronimoSecurityException(
301                     "Unable to generate default principal", de);
302         }
303     }
304
305 }
306
Popular Tags