001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019
020
021 package org.apache.geronimo.openejb;
022
023 import java.util.Map;
024 import java.io.IOException;
025 import java.net.URI;
026
027 import javax.security.auth.spi.LoginModule;
028 import javax.security.auth.Subject;
029 import javax.security.auth.login.LoginException;
030 import javax.security.auth.callback.CallbackHandler;
031 import javax.security.auth.callback.Callback;
032 import javax.security.auth.callback.NameCallback;
033 import javax.security.auth.callback.PasswordCallback;
034 import javax.security.auth.callback.UnsupportedCallbackException;
035
036 import org.apache.openejb.client.ClientSecurity;
037 import org.apache.openejb.client.ServerMetaData;
038 import org.apache.geronimo.security.SubjectId;
039
040 /**
041 * OpenejbRemoteLoginModule uses the openejb protocol to communicate with the server to be used for ejbs and try to
042 * login on that server. If login succeeds an identity token is added to the private credentials of the Subject
043 * that can be used on further calls to identify the client. Note this should only be used on secure networks or
044 * with secured communication with openejb, as sniffing the identity token gives you all the permissions of the user you
045 * sniffed.
046 *
047 * This login module checks security credentials so the lifecycle methods must return true to indicate success
048 * or throw LoginException to indicate failure.
049 *
050 * @version $Rev: 565912 $ $Date: 2007-08-14 17:03:11 -0400 (Tue, 14 Aug 2007) $
051 */
052 public class OpenejbRemoteLoginModule implements LoginModule {
053 private static final String SECURITY_REALM_KEY = "org.apache.geronimo.openejb.OpenejbRemoteLoginModule.RemoteSecurityRealm";
054 private static final String SERVER_URI_KEY = "org.apache.geronimo.openejb.OpenejbRemoteLoginModule.ServerURI";
055
056 private Subject subject;
057 private CallbackHandler callbackHandler;
058 private String securityRealm;
059 private URI serverURI;
060 private SubjectId identity;
061 public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
062 this.subject = subject;
063 this.callbackHandler = callbackHandler;
064 securityRealm = (String) options.get(SECURITY_REALM_KEY);
065 serverURI = URI.create((String) options.get(SERVER_URI_KEY));
066 }
067
068 public boolean login() throws LoginException {
069 Callback[] callbacks = new Callback[] {new NameCallback("username"), new PasswordCallback("passsword", false)};
070 try {
071 callbackHandler.handle(callbacks);
072 } catch (IOException e) {
073 throw (LoginException)new LoginException("Could not execute callbacks").initCause(e);
074 } catch (UnsupportedCallbackException e) {
075 throw (LoginException)new LoginException("Could not execute callbacks").initCause(e);
076 }
077 String userName = ((NameCallback)callbacks[0]).getName();
078 String password = new String(((PasswordCallback)callbacks[1]).getPassword());
079 identity = (SubjectId) ClientSecurity.directAuthentication(securityRealm, userName, password, new ServerMetaData(serverURI));
080 return true;
081 }
082
083 public boolean commit() throws LoginException {
084 subject.getPrivateCredentials().add(new ServerIdentityToken(serverURI, identity));
085 return true;
086 }
087
088 public boolean abort() throws LoginException {
089 subject.getPrivateCredentials().remove(identity);
090 return true;
091 }
092
093 public boolean logout() throws LoginException {
094 //TODO what?
095 return true;
096 }
097 }