1 17 package org.apache.geronimo.jetty.interceptor; 18 19 import java.io.IOException ; 20 import java.security.AccessControlContext ; 21 import java.security.AccessControlException ; 22 import java.security.PermissionCollection ; 23 import java.security.Principal ; 24 import java.util.Map ; 25 import java.util.Set ; 26 import javax.security.auth.Subject ; 27 import javax.security.jacc.PolicyContext ; 28 import javax.security.jacc.PolicyContextException ; 29 import javax.security.jacc.WebResourcePermission ; 30 import javax.security.jacc.WebUserDataPermission ; 31 import javax.servlet.http.HttpServletRequest ; 32 33 import org.apache.geronimo.common.GeronimoSecurityException; 34 import org.apache.geronimo.jetty.JAASJettyPrincipal; 35 import org.apache.geronimo.security.ContextManager; 36 import org.apache.geronimo.security.IdentificationPrincipal; 37 import org.apache.geronimo.security.SubjectId; 38 import org.apache.geronimo.security.deploy.DefaultPrincipal; 39 import org.apache.geronimo.security.util.ConfigurationUtil; 40 import org.mortbay.http.Authenticator; 41 import org.mortbay.http.HttpException; 42 import org.mortbay.http.HttpRequest; 43 import org.mortbay.http.HttpResponse; 44 import org.mortbay.http.SecurityConstraint; 45 import org.mortbay.http.UserRealm; 46 import org.mortbay.jetty.servlet.FormAuthenticator; 47 import org.mortbay.jetty.servlet.ServletHttpRequest; 48 49 50 53 public class SecurityContextBeforeAfter implements BeforeAfter { 54 55 private final BeforeAfter next; 56 private final int policyContextIDIndex; 57 private final int webAppContextIndex; 58 private final String policyContextID; 59 private final static ThreadLocal currentWebAppContext = new ThreadLocal (); 60 private final Map roleDesignates; 61 private final JAASJettyPrincipal defaultPrincipal; 62 63 private final String formLoginPath; 64 65 private final PermissionCollection checked; 66 private final PermissionCollection excludedPermissions; 67 private final Authenticator authenticator; 68 69 private final UserRealm realm; 70 71 public SecurityContextBeforeAfter(BeforeAfter next, 72 int policyContextIDIndex, 73 int webAppContextIndex, 74 String policyContextID, 75 DefaultPrincipal defaultPrincipal, 76 Authenticator authenticator, 77 PermissionCollection checkedPermissions, 78 PermissionCollection excludedPermissions, 79 Map roleDesignates, 80 UserRealm realm) { 81 this.next = next; 82 this.policyContextIDIndex = policyContextIDIndex; 83 this.webAppContextIndex = webAppContextIndex; 84 this.policyContextID = policyContextID; 85 86 this.defaultPrincipal = generateDefaultPrincipal(defaultPrincipal); 87 this.roleDesignates = roleDesignates; 88 this.checked = checkedPermissions; 89 this.excludedPermissions = excludedPermissions; 90 91 if (authenticator instanceof FormAuthenticator) { 92 String formLoginPath = ((FormAuthenticator) authenticator).getLoginPage(); 93 if (formLoginPath.indexOf('?') > 0) { 94 formLoginPath = formLoginPath.substring(0, formLoginPath.indexOf('?')); 95 } 96 this.formLoginPath = formLoginPath; 97 } else { 98 formLoginPath = null; 99 } 100 101 this.authenticator = authenticator; 102 105 Subject defaultSubject = this.defaultPrincipal.getSubject(); 106 ContextManager.registerSubject(defaultSubject); 107 SubjectId id = ContextManager.getSubjectId(defaultSubject); 108 defaultSubject.getPrincipals().add(new IdentificationPrincipal(id)); 109 110 112 113 this.realm = realm; 114 } 116 117 public void stop() { 118 Subject defaultSubject = this.defaultPrincipal.getSubject(); 119 ContextManager.unregisterSubject(defaultSubject); 120 } 121 122 public void before(Object [] context, HttpRequest httpRequest, HttpResponse httpResponse) { 123 context[policyContextIDIndex] = PolicyContext.getContextID(); 124 context[webAppContextIndex] = getCurrentSecurityInterceptor(); 125 126 PolicyContext.setContextID(policyContextID); 127 setCurrentSecurityInterceptor(this); 128 129 if (httpRequest != null){ 130 ServletHttpRequest request = (ServletHttpRequest)httpRequest.getWrapper(); 131 PolicyContext.setHandlerData((HttpServletRequest )request); 132 } 133 134 if (next != null) { 135 next.before(context, httpRequest, httpResponse); 136 } 137 } 138 139 public void after(Object [] context, HttpRequest httpRequest, HttpResponse httpResponse) { 140 if (next != null) { 141 next.after(context, httpRequest, httpResponse); 142 } 143 setCurrentSecurityInterceptor((SecurityContextBeforeAfter) context[webAppContextIndex]); 144 PolicyContext.setContextID((String ) context[policyContextIDIndex]); 145 } 146 147 private static void setCurrentSecurityInterceptor(SecurityContextBeforeAfter context) { 148 SecurityManager sm = System.getSecurityManager(); 149 if (sm != null) sm.checkPermission(ContextManager.SET_CONTEXT); 150 151 currentWebAppContext.set(context); 152 } 153 154 private static SecurityContextBeforeAfter getCurrentSecurityInterceptor() { 155 SecurityManager sm = System.getSecurityManager(); 156 if (sm != null) sm.checkPermission(ContextManager.GET_CONTEXT); 157 158 return (SecurityContextBeforeAfter) currentWebAppContext.get(); 159 } 160 161 public static Subject getCurrentRoleDesignate(String role) { 162 return getCurrentSecurityInterceptor().getRoleDesignate(role); 163 } 164 165 private Subject getRoleDesignate(String roleName) { 166 return (Subject ) roleDesignates.get(roleName); 167 } 168 169 171 180 public boolean checkSecurityConstraints(String pathInContext, HttpRequest request, HttpResponse response) throws HttpException, IOException { 181 if (formLoginPath != null) { 182 String pathToBeTested = (pathInContext.indexOf('?') > 0 ? pathInContext.substring(0, pathInContext.indexOf('?')) : pathInContext); 183 184 if (pathToBeTested.equals(formLoginPath)) { 185 return true; 186 } 187 } 188 189 try { 190 Principal user = obtainUser(pathInContext, request, response); 191 192 if (user == null) { 193 return false; 194 } 195 if (user == SecurityConstraint.__NOBODY) { 196 return true; 197 } 198 199 AccessControlContext acc = ContextManager.getCurrentContext(); 200 ServletHttpRequest servletHttpRequest = (ServletHttpRequest) request.getWrapper(); 201 202 205 206 String transportType; 207 if (request.isConfidential()) { 208 transportType = "CONFIDENTIAL"; 209 } else if (request.isIntegral()) { 210 transportType = "INTEGRAL"; 211 } else { 212 transportType = "NONE"; 213 } 214 WebUserDataPermission wudp = new WebUserDataPermission (servletHttpRequest.getServletPath(), new String []{servletHttpRequest.getMethod()}, transportType); 215 acc.checkPermission(wudp); 216 217 220 acc.checkPermission(new WebResourcePermission (servletHttpRequest)); 221 } catch (HttpException he) { 222 response.sendError(he.getCode(), he.getReason()); 223 return false; 224 } catch (AccessControlException ace) { 225 response.sendError(HttpResponse.__403_Forbidden); 226 return false; 227 } 228 return true; 229 } 230 231 247 private Principal obtainUser(String pathInContext, HttpRequest request, HttpResponse response) throws IOException , IOException { 248 ServletHttpRequest servletHttpRequest = (ServletHttpRequest) request.getWrapper(); 249 WebResourcePermission resourcePermission = new WebResourcePermission (servletHttpRequest); 250 WebUserDataPermission dataPermission = new WebUserDataPermission (servletHttpRequest); 251 boolean unauthenticated = !(checked.implies(resourcePermission) || checked.implies(dataPermission)); 252 boolean forbidden = excludedPermissions.implies(resourcePermission) || excludedPermissions.implies(dataPermission); 253 254 Principal user = null; 256 if (!unauthenticated && !forbidden) { 257 if (realm == null) { 258 throw new HttpException(HttpResponse.__500_Internal_Server_Error, "Realm Not Configured"); 260 } 261 262 263 if (authenticator != null) { 265 user = authenticator.authenticate(realm, pathInContext, request, response); 267 } else { 268 throw new HttpException(HttpResponse.__500_Internal_Server_Error, "Mis-configured Authenticator for " + request.getPath()); 271 } 272 273 return user; 274 } else if (authenticator instanceof FormAuthenticator && pathInContext.endsWith(FormAuthenticator.__J_SECURITY_CHECK)) { 275 278 if (realm == null) { 279 throw new HttpException(HttpResponse.__500_Internal_Server_Error, "Realm Not Configured"); 281 } 282 return authenticator.authenticate(realm, pathInContext, request, response); 283 } 284 285 288 ContextManager.setCurrentCaller(defaultPrincipal.getSubject()); 289 return defaultPrincipal; 290 } 291 292 293 299 protected JAASJettyPrincipal generateDefaultPrincipal(DefaultPrincipal defaultPrincipal) throws GeronimoSecurityException { 300 301 if (defaultPrincipal == null) { 302 throw new GeronimoSecurityException("Unable to generate default principal"); 303 } 304 305 JAASJettyPrincipal result = new JAASJettyPrincipal("default"); 306 Subject defaultSubject = ConfigurationUtil.generateDefaultSubject(defaultPrincipal); 307 308 result.setSubject(defaultSubject); 309 310 return result; 311 } 312 313 } 314 | Popular Tags |