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 }