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 }