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.providers;
018    
019    import java.util.Map;
020    
021    import javax.security.auth.Subject;
022    import javax.security.auth.callback.CallbackHandler;
023    import javax.security.auth.login.LoginException;
024    import javax.security.auth.spi.LoginModule;
025    
026    /**
027     * ConstantLoginModule allows a single user and multiple group
028     * principals to be added to an authenticated Subject via
029     * configuration during application deployment. ConstantLoginModule
030     * would normally be used along with a more conventional LoginModule. A
031     * potential use case for ConstantLoginModule is a situation where you
032     * want to associate a single user (or group) to an authenticated user,
033     * but the authentication mechanism does not contain such a group.
034     * For example, ConstantLoginModule could allow an "Authenticated" 
035     * user principal to be added to the Subject.
036     * <p>
037     * To configure, add the following to the <login-config> of your geronimo deployment plan:
038     * <code>
039     *   <log:login-module control-flag="REQUIRED" wrap-principals="false">
040     *       <log:login-domain-name>Constant</log:login-domain-name>
041     *       <log:login-module-class>org.apache.geronimo.security.realm.providers.ConstantLoginModule</log:login-module-class>
042     *       <log:option name="userName">authenticated</log:option>
043     *       <log:option name="groupNames">group1,group2</log:option>
044     *   </log:login-module>
045     * </code>
046     */
047    public class ConstantLoginModule implements LoginModule {
048    
049        private Subject subject;
050        private CallbackHandler handler;
051        
052        private String userName;
053        private String groupNames;
054        
055        private static final String USER_NAME = "userName";
056        private static final String GROUP_NAMES = "groupNames";
057        
058        public boolean abort() throws LoginException {
059            return true;
060        }
061    
062        /**
063         * Add the user and group principals to the Subject. Group names are separated
064         * by ',' characters.
065         */
066        public boolean commit() throws LoginException {
067            if(userName != null) {
068                subject.getPrincipals().add(new GeronimoUserPrincipal(userName));
069            }
070            
071            if(groupNames != null) {
072                for (String groupName : groupNames.split(",")) {
073                    subject.getPrincipals().add(new GeronimoGroupPrincipal(groupName));
074                }
075            }
076            
077            return true;
078        }
079    
080        /**
081         * Save the userName and groupNames settings for use during commit()
082         */
083        public void initialize(Subject subject, CallbackHandler callbackHandler,
084                Map sharedState, Map options) {
085    
086            this.subject = subject;
087            this.handler = handler;
088            
089            this.userName = (String)options.get(USER_NAME);
090            this.groupNames = (String)options.get(GROUP_NAMES);
091        }
092    
093        public boolean login() throws LoginException {
094            return true;
095        }
096    
097        public boolean logout() throws LoginException {
098            return true;
099        }
100    
101    }