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.realm;
018    
019    import java.util.ArrayList;
020    import java.util.HashSet;
021    import java.util.List;
022    import java.util.Properties;
023    import java.util.Set;
024    
025    import javax.security.auth.login.AppConfigurationEntry;
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.jaas.ConfigurationEntryFactory;
032    import org.apache.geronimo.security.jaas.JaasLoginModuleChain;
033    import org.apache.geronimo.security.jaas.JaasLoginModuleUse;
034    import org.apache.geronimo.system.serverinfo.ServerInfo;
035    
036    
037    /**
038     * A security realm that can be configured for one or more login modules.  It
039     * can handle a combination of client-side and server-side login modules for
040     * the case of remote clients, and it can auto-role-mapping for its login
041     * modules (though you must configure it for that).
042     * <p/>
043     * This realm populates a number of special login module options for the
044     * benefit of Geronimo login modules (though some of them are only available to
045     * server-side login modules, marked as not Serializable below):
046     * <pre>
047     * Option                                      Type                   Serializable
048     * JaasLoginModuleUse.KERNEL_LM_OPTION       String (Kernel name)        Yes
049     * JaasLoginModuleUse.SERVERINFO_LM_OPTION   ServerInfo                  No
050     * JaasLoginModuleUse.CLASSLOADER_LM_OPTION  ClassLoader                 No
051     * </pre>
052     * These options can be safely ignored by login modules that don't need them
053     * (such as any custom LoginModules you may already have lying around).
054     *
055     * @version $Rev: 565912 $ $Date: 2007-08-14 17:03:11 -0400 (Tue, 14 Aug 2007) $
056     */
057    public class GenericSecurityRealm implements SecurityRealm, ConfigurationEntryFactory {
058    
059        private final String realmName;
060        private AppConfigurationEntry[] config;
061    
062        private String[] domains;
063        private final boolean wrapPrincipals;
064        private final JaasLoginModuleUse loginModuleUse;
065    
066        public GenericSecurityRealm(String realmName,
067                                    JaasLoginModuleUse loginModuleUse,
068                                    boolean wrapPrincipals,
069                                    ServerInfo serverInfo,
070                                    ClassLoader classLoader,
071                                    Kernel kernel
072        ) throws ClassNotFoundException {
073            this.realmName = realmName;
074            this.wrapPrincipals = wrapPrincipals;
075            this.loginModuleUse = loginModuleUse;
076    
077            Set<String> domainNames = new HashSet<String>();
078            List<AppConfigurationEntry> loginModuleConfigurations = new ArrayList<AppConfigurationEntry>();
079    
080            if (loginModuleUse != null) {
081                loginModuleUse.configure(domainNames, loginModuleConfigurations, realmName, kernel, serverInfo, classLoader);
082            }
083    
084            domains = domainNames.toArray(new String[domainNames.size()]);
085            config = loginModuleConfigurations.toArray(new AppConfigurationEntry[loginModuleConfigurations.size()]);
086    
087        }
088    
089        public String getRealmName() {
090            return realmName;
091        }
092    
093        public AppConfigurationEntry[] getAppConfigurationEntries() {
094            return config;
095        }
096    
097        public JaasLoginModuleChain getLoginModuleChain() {
098            return loginModuleUse;
099        }
100    
101        /**
102         * Gets a list of the login domains that make up this security realm.  A
103         * particular LoginModule represents 0 or 1 login domains, and a realm is
104         * composed of a number of login modules, so the realm may cover any
105         * number of login domains, though typically that number will be 1.
106         */
107        public String[] getLoginDomains() {
108            return domains;
109        }
110    
111        /**
112         * If this attribute is true, then the principals will be wrapped in
113         * realm principals.
114         */
115        public boolean isWrapPrincipals() {
116            return wrapPrincipals;
117        }
118    
119        public String getConfigurationName() {
120            return realmName;
121        }
122    
123        public static final GBeanInfo GBEAN_INFO;
124    
125        static {
126            GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(GenericSecurityRealm.class, NameFactory.SECURITY_REALM);
127    
128            infoFactory.addInterface(SecurityRealm.class);
129            infoFactory.addInterface(ConfigurationEntryFactory.class);
130            infoFactory.addAttribute("realmName", String.class, true);
131            infoFactory.addAttribute("kernel", Kernel.class, false);
132            infoFactory.addAttribute("classLoader", ClassLoader.class, false);
133            infoFactory.addAttribute("deploymentSupport", Properties.class, true);
134            infoFactory.addAttribute("wrapPrincipals", boolean.class, true);
135    
136            infoFactory.addReference("LoginModuleConfiguration", JaasLoginModuleUse.class, "LoginModuleUse");
137            infoFactory.addReference("ServerInfo", ServerInfo.class, NameFactory.GERONIMO_SERVICE);
138    
139            infoFactory.setConstructor(new String[]{"realmName",
140                                                    "LoginModuleConfiguration",
141                                                    "wrapPrincipals",
142                                                    "ServerInfo",
143                                                    "classLoader",
144                                                    "kernel"});
145    
146            GBEAN_INFO = infoFactory.getBeanInfo();
147        }
148    
149        public static GBeanInfo getGBeanInfo() {
150            return GBEAN_INFO;
151        }
152    
153    }