001 /** 002 * 003 * Copyright 2003-2004 The Apache Software Foundation 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * 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.realm; 018 019 import java.util.ArrayList; 020 import java.util.HashMap; 021 import java.util.HashSet; 022 import java.util.List; 023 import java.util.Map; 024 import java.util.Properties; 025 import java.util.Set; 026 027 import org.apache.geronimo.gbean.GBeanInfo; 028 import org.apache.geronimo.gbean.GBeanInfoBuilder; 029 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 030 import org.apache.geronimo.kernel.Kernel; 031 import org.apache.geronimo.security.deploy.PrincipalInfo; 032 import org.apache.geronimo.security.jaas.ConfigurationEntryFactory; 033 import org.apache.geronimo.security.jaas.client.JaasLoginCoordinator; 034 import org.apache.geronimo.security.jaas.server.JaasLoginModuleConfiguration; 035 import org.apache.geronimo.security.jaas.JaasLoginModuleUse; 036 import org.apache.geronimo.security.jaas.LoginModuleControlFlag; 037 import org.apache.geronimo.security.jaas.JaasLoginModuleChain; 038 import org.apache.geronimo.security.jaas.server.JaasLoginServiceMBean; 039 import org.apache.geronimo.system.serverinfo.ServerInfo; 040 041 042 /** 043 * A security realm that can be configured for one or more login modules. It 044 * can handle a combination of client-side and server-side login modules for 045 * the case of remote clients, and it can auto-role-mapping for its login 046 * modules (though you must configure it for that). 047 * <p/> 048 * This realm populates a number of special login module options for the 049 * benefit of Geronimo login modules (though some of them are only available to 050 * server-side login modules, marked as not Serializable below): 051 * <pre> 052 * Option Type Serializable 053 * JaasLoginModuleUse.KERNEL_LM_OPTION String (Kernel name) Yes 054 * JaasLoginModuleUse.SERVERINFO_LM_OPTION ServerInfo No 055 * JaasLoginModuleUse.CLASSLOADER_LM_OPTION ClassLoader No 056 * </pre> 057 * These options can be safely ignored by login modules that don't need them 058 * (such as any custom LoginModules you may already have lying around). 059 * 060 * @version $Rev: 391894 $ $Date: 2006-04-05 21:00:33 -0700 (Wed, 05 Apr 2006) $ 061 */ 062 public class GenericSecurityRealm implements SecurityRealm, ConfigurationEntryFactory { 063 064 private final JaasLoginServiceMBean loginService; 065 private final String realmName; 066 private JaasLoginModuleConfiguration[] config; 067 private final Kernel kernel; 068 069 private final PrincipalInfo defaultPrincipalInfo; 070 071 private String[] domains; 072 private final boolean restrictPrincipalsToServer; 073 private final boolean wrapPrincipals; 074 private final JaasLoginModuleUse loginModuleUse; 075 076 public GenericSecurityRealm(String realmName, 077 JaasLoginModuleUse loginModuleUse, 078 boolean restrictPrincipalsToServer, 079 boolean wrapPrincipals, 080 PrincipalInfo defaultPrincipalInfo, 081 ServerInfo serverInfo, 082 ClassLoader classLoader, 083 Kernel kernel, 084 JaasLoginServiceMBean loginService) { 085 this.realmName = realmName; 086 this.kernel = kernel; 087 this.restrictPrincipalsToServer = restrictPrincipalsToServer; 088 this.wrapPrincipals = wrapPrincipals; 089 this.defaultPrincipalInfo = defaultPrincipalInfo; 090 this.loginService = loginService; 091 this.loginModuleUse = loginModuleUse; 092 093 Set domainNames = new HashSet(); 094 List loginModuleConfigurations = new ArrayList(); 095 096 if (loginModuleUse != null) { 097 loginModuleUse.configure(domainNames, loginModuleConfigurations, kernel, serverInfo, classLoader); 098 } 099 100 domains = (String[]) domainNames.toArray(new String[domainNames.size()]); 101 config = (JaasLoginModuleConfiguration[]) loginModuleConfigurations.toArray(new JaasLoginModuleConfiguration[loginModuleConfigurations.size()]); 102 103 } 104 105 public String getRealmName() { 106 return realmName; 107 } 108 109 public JaasLoginModuleConfiguration[] getAppConfigurationEntries() { 110 return config; 111 } 112 113 public JaasLoginModuleChain getLoginModuleChain() { 114 return loginModuleUse; 115 } 116 117 /** 118 * Gets a list of the login domains that make up this security realm. A 119 * particular LoginModule represents 0 or 1 login domains, and a realm is 120 * composed of a number of login modules, so the realm may cover any 121 * number of login domains, though typically that number will be 1. 122 */ 123 public String[] getLoginDomains() { 124 return domains; 125 } 126 127 128 /** 129 * Provides the default principal to be used when an unauthenticated 130 * subject uses a container. 131 * 132 * @return the default principal 133 */ 134 public PrincipalInfo getDefaultPrincipal() { 135 return defaultPrincipalInfo; 136 } 137 138 /** 139 * A GBean property. If set to true, the login service will not return 140 * principals generated by this realm to clients. If set to false (the 141 * default), the client will get a copy of all principals (except realm 142 * principals generated strictly for use within Geronimo). 143 */ 144 public boolean isRestrictPrincipalsToServer() { 145 return restrictPrincipalsToServer; 146 } 147 148 /** 149 * If this attribute is true, then the principals will be wrapped in 150 * realm principals. 151 */ 152 public boolean isWrapPrincipals() { 153 return wrapPrincipals; 154 } 155 156 public String getConfigurationName() { 157 return realmName; 158 } 159 160 public JaasLoginModuleConfiguration generateConfiguration() { 161 Map options = new HashMap(); 162 options.put(JaasLoginCoordinator.OPTION_REALM, realmName); 163 if (kernel != null) { 164 options.put(JaasLoginCoordinator.OPTION_KERNEL, kernel.getKernelName()); 165 if (loginService != null) { 166 options.put(JaasLoginCoordinator.OPTION_SERVICENAME, loginService.getObjectName()); 167 } 168 } else { 169 if (loginService != null) { 170 //this can be used for testing without a kernel. 171 options.put(JaasLoginCoordinator.OPTION_SERVICE_INSTANCE, loginService); 172 } 173 } 174 175 return new JaasLoginModuleConfiguration(JaasLoginCoordinator.class.getName(), LoginModuleControlFlag.REQUIRED, options, true, realmName, wrapPrincipals, JaasLoginCoordinator.class.getClassLoader()); 176 } 177 178 public static final GBeanInfo GBEAN_INFO; 179 180 static { 181 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(GenericSecurityRealm.class, NameFactory.SECURITY_REALM); 182 183 infoFactory.addInterface(SecurityRealm.class); 184 infoFactory.addInterface(ConfigurationEntryFactory.class); 185 infoFactory.addAttribute("realmName", String.class, true); 186 infoFactory.addAttribute("kernel", Kernel.class, false); 187 infoFactory.addAttribute("classLoader", ClassLoader.class, false); 188 infoFactory.addAttribute("defaultPrincipal", PrincipalInfo.class, true); 189 infoFactory.addAttribute("deploymentSupport", Properties.class, true); 190 infoFactory.addAttribute("restrictPrincipalsToServer", boolean.class, true); 191 infoFactory.addAttribute("wrapPrincipals", boolean.class, true); 192 193 infoFactory.addReference("LoginModuleConfiguration", JaasLoginModuleUse.class, "LoginModuleUse"); 194 infoFactory.addReference("ServerInfo", ServerInfo.class, NameFactory.GERONIMO_SERVICE); 195 infoFactory.addReference("LoginService", JaasLoginServiceMBean.class, "JaasLoginService"); 196 197 infoFactory.addOperation("getAppConfigurationEntries", new Class[0]); 198 199 infoFactory.setConstructor(new String[]{"realmName", 200 "LoginModuleConfiguration", 201 "restrictPrincipalsToServer", 202 "wrapPrincipals", 203 "defaultPrincipal", 204 "ServerInfo", 205 "classLoader", 206 "kernel", 207 "LoginService"}); 208 209 GBEAN_INFO = infoFactory.getBeanInfo(); 210 } 211 212 public static GBeanInfo getGBeanInfo() { 213 return GBEAN_INFO; 214 } 215 216 }