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    }