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.io.IOException;
020    import java.util.Map;
021    import java.util.Set;
022    import javax.security.auth.Subject;
023    import javax.security.auth.DestroyFailedException;
024    import javax.security.auth.callback.Callback;
025    import javax.security.auth.callback.CallbackHandler;
026    import javax.security.auth.callback.NameCallback;
027    import javax.security.auth.callback.PasswordCallback;
028    import javax.security.auth.callback.UnsupportedCallbackException;
029    import javax.security.auth.login.LoginException;
030    import javax.security.auth.spi.LoginModule;
031    
032    
033    /**
034     *
035     *
036     * Inserts Username/Password credential into private credentials of Subject.
037     * <p/>
038     * If either the username or password is not passed in the callback handler,
039     * then the credential is not placed into the Subject.
040     *
041     * This login module does not check credentials so it should never be able to cause a login to succeed.
042     * Therefore the lifecycle methods must return false to indicate success or throw a LoginException to indicate failure.
043     *
044     * @version $Revision: 565912 $ $Date: 2007-08-14 17:03:11 -0400 (Tue, 14 Aug 2007) $
045     */
046    public class UPCredentialLoginModule implements LoginModule {
047    
048        private Subject subject;
049        private CallbackHandler callbackHandler;
050        private UsernamePasswordCredential upCredential;
051    
052        public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
053    
054            this.subject = subject;
055            this.callbackHandler = callbackHandler;
056        }
057    
058        public boolean login() throws LoginException {
059    
060            Callback[] callbacks = new Callback[2];
061    
062            callbacks[0] = new NameCallback("User name");
063            callbacks[1] = new PasswordCallback("Password", false);
064            try {
065                callbackHandler.handle(callbacks);
066            } catch (IOException ioe) {
067                throw (LoginException) new LoginException().initCause(ioe);
068            } catch (UnsupportedCallbackException uce) {
069                throw (LoginException) new LoginException().initCause(uce);
070            }
071    
072            String username = ((NameCallback) callbacks[0]).getName();
073            char[] password = ((PasswordCallback) callbacks[1]).getPassword();
074    
075            if (username == null || password == null) return false;
076    
077            upCredential = new UsernamePasswordCredential(username, password);
078    
079            return false;
080        }
081    
082        public boolean commit() throws LoginException {
083    
084            if (subject.isReadOnly()) {
085                throw new LoginException("Subject is ReadOnly");
086            }
087    
088            Set pvtCreds = subject.getPrivateCredentials();
089            if (upCredential != null && !pvtCreds.contains(upCredential)) {
090                pvtCreds.add(upCredential);
091            }
092    
093            return false;
094        }
095    
096        public boolean abort() throws LoginException {
097    
098            return logout();
099        }
100    
101        public boolean logout() throws LoginException {
102    
103            if (upCredential == null) return true;
104    
105            Set pvtCreds = subject.getPrivateCredentials(UsernamePasswordCredential.class);
106            if (pvtCreds.contains(upCredential)) {
107                pvtCreds.remove(upCredential);
108            }
109    
110            try {
111                upCredential.destroy();
112            } catch (DestroyFailedException e) {
113                // do nothing
114            }
115            upCredential = null;
116    
117            return false;
118        }
119    
120    }