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.List;
022 import java.util.Map;
023 import java.util.Set;
024 import javax.security.auth.spi.LoginModule;
025 import javax.security.auth.Subject;
026 import javax.security.auth.DestroyFailedException;
027 import javax.security.auth.login.LoginException;
028 import javax.security.auth.callback.CallbackHandler;
029
030 import org.apache.commons.logging.Log;
031 import org.apache.commons.logging.LogFactory;
032
033 /**
034 * ConfiguredIdentityNamedUsernamePasswordLoginModule adds a geronimo-specific NamedUsernamePasswordCredential
035 * to the subject constructed from the configured username, password, and credential name. This is useful in
036 * supplying fixed credentials to e.g. web service calls.
037 *
038 * Note that this places passwords to external services in configuration information. It may be more appropriate
039 * to use the GeronimoPropertiesFileMappedPasswordCredentialLoginModule or a run-as subject with a
040 * NamedUsernamePasswordCredentialLoginModule although the latter solution may put a credential in a
041 * credential store configuration.
042 *
043 * This login module does not check credentials so it should never be able to cause a login to succeed.
044 * Therefore the lifecycle methods must return false to indicate success or throw a LoginException to indicate failure.
045 *
046 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
047 */
048 public class ConfiguredIdentityNamedUsernamePasswordLoginModule implements LoginModule {
049 private static Log log = LogFactory.getLog(ConfiguredIdentityNamedUsernamePasswordLoginModule.class);
050
051 public static final String CREDENTIAL_NAME = "org.apache.geronimo.jaas.NamedUsernamePasswordCredential.Name";
052 public static final String USER_NAME = "org.apache.geronimo.jaas.NamedUsernamePasswordCredential.Username";
053 public static final String PASSWORD = "org.apache.geronimo.jaas.NamedUsernamePasswordCredential.Password";
054 public final static List<String> supportedOptions = Collections.unmodifiableList(Arrays.asList(CREDENTIAL_NAME, USER_NAME, PASSWORD));
055
056 private Subject subject;
057 private NamedUsernamePasswordCredential namedUsernamePasswordCredential;
058 private String name, username, password;
059
060 public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) {
061 this.subject = subject;
062 for(Object option: options.keySet()) {
063 if(!supportedOptions.contains(option) && !JaasLoginModuleUse.supportedOptions.contains(option)
064 && !WrappingLoginModule.supportedOptions.contains(option)) {
065 log.warn("Ignoring option: "+option+". Not supported.");
066 }
067 }
068 name = (String) options.get(CREDENTIAL_NAME);
069 username = (String) options.get(USER_NAME);
070 password = (String) options.get(PASSWORD);
071 }
072
073 public boolean login() throws LoginException {
074 return false;
075 }
076
077 public boolean commit() throws LoginException {
078 if (subject.isReadOnly()) {
079 throw new LoginException("Subject is ReadOnly");
080 }
081
082 namedUsernamePasswordCredential = new NamedUsernamePasswordCredential(username, password.toCharArray(), name);
083 subject.getPrivateCredentials().add(namedUsernamePasswordCredential);
084
085 return false;
086 }
087
088 public boolean abort() throws LoginException {
089 return logout();
090 }
091
092 public boolean logout() throws LoginException {
093 if (namedUsernamePasswordCredential == null) {
094 return false;
095 }
096
097 Set pvtCreds = subject.getPrivateCredentials();
098 if (!subject.isReadOnly()) {
099 pvtCreds.remove(namedUsernamePasswordCredential);
100 }
101
102 try {
103 namedUsernamePasswordCredential.destroy();
104 } catch (DestroyFailedException e) {
105 // do nothing
106 }
107 namedUsernamePasswordCredential = null;
108
109 return false;
110 }
111 }