001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.geronimo.security.jacc; 018 019 import java.security.Permission; 020 import java.security.PermissionCollection; 021 import java.security.Policy; 022 import java.util.Enumeration; 023 import java.util.HashMap; 024 import java.util.Map; 025 026 import javax.security.auth.Subject; 027 import javax.security.auth.login.LoginException; 028 import javax.security.jacc.PolicyConfiguration; 029 import javax.security.jacc.PolicyConfigurationFactory; 030 import javax.security.jacc.PolicyContextException; 031 032 import org.apache.geronimo.gbean.GBeanInfo; 033 import org.apache.geronimo.gbean.GBeanInfoBuilder; 034 import org.apache.geronimo.gbean.GBeanLifecycle; 035 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 036 import org.apache.geronimo.security.ContextManager; 037 import org.apache.geronimo.security.IdentificationPrincipal; 038 import org.apache.geronimo.security.SubjectId; 039 import org.apache.geronimo.security.credentialstore.CredentialStore; 040 import org.apache.geronimo.security.deploy.SubjectInfo; 041 042 /** 043 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 044 */ 045 public class ApplicationPolicyConfigurationManager implements GBeanLifecycle, RunAsSource { 046 047 private final Map<String, PolicyConfiguration> contextIdToPolicyConfigurationMap = new HashMap<String, PolicyConfiguration>(); 048 private final Map<String, Subject> roleDesignates = new HashMap<String, Subject>(); 049 private final Subject defaultSubject; 050 private final PrincipalRoleMapper principalRoleMapper; 051 052 public ApplicationPolicyConfigurationManager(Map<String, ComponentPermissions> contextIdToPermissionsMap, SubjectInfo defaultSubjectInfo, Map<String, SubjectInfo> roleDesignates, ClassLoader cl, CredentialStore credentialStore, PrincipalRoleMapper principalRoleMapper) throws PolicyContextException, ClassNotFoundException, LoginException { 053 if (credentialStore == null && (!roleDesignates.isEmpty() || defaultSubjectInfo != null)) { 054 throw new NullPointerException("No CredentialStore supplied to resolve default and run-as subjects"); 055 } 056 this.principalRoleMapper = principalRoleMapper; 057 Thread currentThread = Thread.currentThread(); 058 ClassLoader oldClassLoader = currentThread.getContextClassLoader(); 059 currentThread.setContextClassLoader(cl); 060 PolicyConfigurationFactory policyConfigurationFactory; 061 try { 062 policyConfigurationFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory(); 063 } finally { 064 currentThread.setContextClassLoader(oldClassLoader); 065 } 066 067 for (Map.Entry<String, ComponentPermissions> entry : contextIdToPermissionsMap.entrySet()) { 068 String contextID = entry.getKey(); 069 ComponentPermissions componentPermissions = entry.getValue(); 070 071 PolicyConfiguration policyConfiguration = policyConfigurationFactory.getPolicyConfiguration(contextID, true); 072 contextIdToPolicyConfigurationMap.put(contextID, policyConfiguration); 073 policyConfiguration.addToExcludedPolicy(componentPermissions.getExcludedPermissions()); 074 policyConfiguration.addToUncheckedPolicy(componentPermissions.getUncheckedPermissions()); 075 for (Map.Entry<String, PermissionCollection> roleEntry : componentPermissions.getRolePermissions().entrySet()) { 076 String roleName = roleEntry.getKey(); 077 PermissionCollection rolePermissions = roleEntry.getValue(); 078 for (Enumeration permissions = rolePermissions.elements(); permissions.hasMoreElements();) { 079 Permission permission = (Permission) permissions.nextElement(); 080 policyConfiguration.addToRole(roleName, permission); 081 082 } 083 } 084 } 085 086 if (principalRoleMapper != null) { 087 principalRoleMapper.install(contextIdToPermissionsMap.keySet()); 088 } 089 090 //link everything together 091 for (PolicyConfiguration policyConfiguration : contextIdToPolicyConfigurationMap.values()) { 092 for (PolicyConfiguration policyConfiguration2 : contextIdToPolicyConfigurationMap.values()) { 093 if (policyConfiguration != policyConfiguration2) { 094 policyConfiguration.linkConfiguration(policyConfiguration2); 095 } 096 } 097 } 098 099 //commit 100 for (PolicyConfiguration policyConfiguration : contextIdToPolicyConfigurationMap.values()) { 101 policyConfiguration.commit(); 102 } 103 104 //refresh policy 105 Policy policy = Policy.getPolicy(); 106 policy.refresh(); 107 108 if (defaultSubjectInfo == null) { 109 defaultSubject = ContextManager.EMPTY; 110 } else { 111 defaultSubject = credentialStore.getSubject(defaultSubjectInfo.getRealm(), defaultSubjectInfo.getId()); 112 registerSubject(defaultSubject); 113 } 114 115 for (Map.Entry<String, SubjectInfo> entry : roleDesignates.entrySet()) { 116 String role = entry.getKey(); 117 SubjectInfo subjectInfo = entry.getValue(); 118 if (subjectInfo == null || credentialStore == null) { 119 throw new NullPointerException("No subjectInfo for role " + role); 120 } 121 Subject roleDesignate = credentialStore.getSubject(subjectInfo.getRealm(), subjectInfo.getId()); 122 registerSubject(roleDesignate); 123 this.roleDesignates.put(role, roleDesignate); 124 } 125 } 126 127 private void registerSubject(Subject subject) { 128 ContextManager.registerSubject(subject); 129 SubjectId id = ContextManager.getSubjectId(subject); 130 subject.getPrincipals().add(new IdentificationPrincipal(id)); 131 } 132 133 public Subject getDefaultSubject() { 134 return defaultSubject; 135 } 136 137 public Subject getSubjectForRole(String role) { 138 return roleDesignates.get(role); 139 } 140 141 public void doStart() throws Exception { 142 143 } 144 145 public void doStop() throws Exception { 146 for (Map.Entry<String, Subject> entry : roleDesignates.entrySet()) { 147 Subject roleDesignate = entry.getValue(); 148 ContextManager.unregisterSubject(roleDesignate); 149 } 150 if (defaultSubject != ContextManager.EMPTY) { 151 ContextManager.unregisterSubject(defaultSubject); 152 } 153 154 if (principalRoleMapper != null) { 155 principalRoleMapper.uninstall(contextIdToPolicyConfigurationMap.keySet()); 156 } 157 158 for (PolicyConfiguration policyConfiguration : contextIdToPolicyConfigurationMap.values()) { 159 policyConfiguration.delete(); 160 } 161 } 162 163 public void doFail() { 164 165 } 166 167 public static final GBeanInfo GBEAN_INFO; 168 169 static { 170 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(ApplicationPolicyConfigurationManager.class, NameFactory.JACC_MANAGER); 171 infoBuilder.addAttribute("contextIdToPermissionsMap", Map.class, true); 172 infoBuilder.addAttribute("defaultSubjectInfo", SubjectInfo.class, true); 173 infoBuilder.addAttribute("roleDesignates", Map.class, true); 174 infoBuilder.addAttribute("classLoader", ClassLoader.class, false); 175 infoBuilder.addReference("CredentialStore", CredentialStore.class, NameFactory.GERONIMO_SERVICE); 176 infoBuilder.addReference("PrincipalRoleMapper", PrincipalRoleMapper.class, NameFactory.JACC_MANAGER); 177 infoBuilder.setConstructor(new String[] {"contextIdToPermissionsMap", "defaultSubjectInfo", "roleDesignates", "classLoader", "CredentialStore", "PrincipalRoleMapper"}); 178 GBEAN_INFO = infoBuilder.getBeanInfo(); 179 } 180 181 public static GBeanInfo getGBeanInfo() { 182 return GBEAN_INFO; 183 } 184 }