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.jaas;
018
019 import java.util.Arrays;
020 import java.util.Collections;
021 import java.util.HashMap;
022 import java.util.List;
023 import java.util.Map;
024 import java.util.Set;
025
026 import javax.security.auth.login.AppConfigurationEntry;
027
028 import org.apache.geronimo.gbean.GBeanInfo;
029 import org.apache.geronimo.gbean.GBeanInfoBuilder;
030 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
031 import org.apache.geronimo.kernel.Kernel;
032 import org.apache.geronimo.system.serverinfo.ServerInfo;
033
034
035 /**
036 * Holds a reference to a login module and the control flag. A linked list of these forms the list of login modules
037 * in a GenericSecurityRealm.
038 *
039 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
040 */
041 public class JaasLoginModuleUse implements JaasLoginModuleChain {
042 // See also http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASLMDevGuide.html for more standard login module option keys
043 public final static String KERNEL_NAME_LM_OPTION = "org.apache.geronimo.security.realm.GenericSecurityRealm.KERNEL";
044 public final static String SERVERINFO_LM_OPTION = "org.apache.geronimo.security.realm.GenericSecurityRealm.SERVERINFO";
045 public final static String CLASSLOADER_LM_OPTION = "org.apache.geronimo.security.realm.GenericSecurityRealm.CLASSLOADER";
046 public final static List<String> supportedOptions = Collections.unmodifiableList(Arrays.asList(KERNEL_NAME_LM_OPTION, SERVERINFO_LM_OPTION, CLASSLOADER_LM_OPTION));
047
048 private final LoginModuleSettings loginModule;
049 private final JaasLoginModuleUse next;
050 private LoginModuleControlFlag controlFlag;
051
052 //for reference.
053 public JaasLoginModuleUse() {
054 loginModule = null;
055 next = null;
056 controlFlag = null;
057 }
058
059 public JaasLoginModuleUse(LoginModuleSettings loginModule, JaasLoginModuleUse next, LoginModuleControlFlag controlFlag) {
060 this.loginModule = loginModule;
061 this.next = next;
062 this.controlFlag = controlFlag;
063 }
064
065 public LoginModuleSettings getLoginModule() {
066 return loginModule;
067 }
068
069 public JaasLoginModuleChain getNext() {
070 return next;
071 }
072
073 public LoginModuleControlFlag getControlFlag() {
074 return controlFlag;
075 }
076
077 public void setControlFlag(LoginModuleControlFlag controlFlag) {
078 this.controlFlag = controlFlag;
079 }
080
081 public void configure(Set<String> domainNames, List<AppConfigurationEntry> loginModuleConfigurations, String realmName, Kernel kernel, ServerInfo serverInfo, ClassLoader classLoader) throws ClassNotFoundException {
082 Map<String, ?> suppliedOptions = loginModule.getOptions();
083 Map<String, Object> options;
084 if (suppliedOptions != null) {
085 options = new HashMap<String, Object>(suppliedOptions);
086 } else {
087 options = new HashMap<String, Object>();
088 }
089 if (kernel != null && !options.containsKey(KERNEL_NAME_LM_OPTION)) {
090 options.put(KERNEL_NAME_LM_OPTION, kernel.getKernelName());
091 }
092 if (serverInfo != null && !options.containsKey(SERVERINFO_LM_OPTION)) {
093 options.put(SERVERINFO_LM_OPTION, serverInfo);
094 }
095 if (!options.containsKey(CLASSLOADER_LM_OPTION)) {
096 options.put(CLASSLOADER_LM_OPTION, classLoader);
097 }
098 AppConfigurationEntry entry;
099 Class loginModuleClass;
100 loginModuleClass = classLoader.loadClass(loginModule.getLoginModuleClass());
101 options.put(WrappingLoginModule.CLASS_OPTION, loginModuleClass);
102 if (loginModule.isWrapPrincipals()) {
103 options.put(WrappingLoginModule.DOMAIN_OPTION, loginModule.getLoginDomainName());
104 options.put(WrappingLoginModule.REALM_OPTION, realmName);
105 entry = new AppConfigurationEntry(WrappingLoginModule.class.getName(), controlFlag.getFlag(), options);
106 } else {
107 entry = new AppConfigurationEntry(ClassOptionLoginModule.class.getName(), controlFlag.getFlag(), options);
108 }
109 if (loginModule.getLoginDomainName() != null) {
110 if (domainNames.contains(loginModule.getLoginDomainName())) {
111 throw new IllegalStateException("Error in realm: one security realm cannot contain multiple login modules for the same login domain");
112 } else {
113 domainNames.add(loginModule.getLoginDomainName());
114 }
115 }
116 loginModuleConfigurations.add(entry);
117
118 if (next != null) {
119 next.configure(domainNames, loginModuleConfigurations, realmName, kernel, serverInfo, classLoader);
120 }
121 }
122
123 public static final GBeanInfo GBEAN_INFO;
124
125 static {
126 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JaasLoginModuleUse.class, "LoginModuleUse");
127 infoBuilder.addAttribute("controlFlag", LoginModuleControlFlag.class, true);
128 infoBuilder.addReference("LoginModule", LoginModuleSettings.class, NameFactory.LOGIN_MODULE);
129 infoBuilder.addReference("Next", JaasLoginModuleUse.class);
130
131 infoBuilder.addInterface(JaasLoginModuleChain.class);
132 infoBuilder.setConstructor(new String[]{"LoginModule", "Next", "controlFlag"});
133 GBEAN_INFO = infoBuilder.getBeanInfo();
134 }
135
136 public static GBeanInfo getGBeanInfo() {
137 return GBEAN_INFO;
138 }
139 }