package org.marketcetera.modules.remote.receiver;
import org.marketcetera.core.ClassVersion;
import org.marketcetera.util.log.SLF4JLoggerProxy;
import org.marketcetera.client.ClientInitException;
import javax.security.auth.spi.LoginModule;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.AccountNotFoundException;
import javax.security.auth.callback.*;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.io.IOException;
import java.security.Principal;
import com.sun.security.auth.UserPrincipal;
/* $License$ */
/**
* Login module that authenticates by supplying the provided credentials to
* {@link org.marketcetera.client.Client#isCredentialsMatch(String, char[])}.
* <p>
* This login module doesn't accept any configuration options and it
* logs to the log file via the system logging mechanism.
*
* @author anshul@marketcetera.com
* @version $Id: ClientLoginModule.java 16841 2014-02-20 19:59:04Z colin $
* @since 1.5.0
*/
@ClassVersion("$Id: ClientLoginModule.java 16841 2014-02-20 19:59:04Z colin $") //$NON-NLS-1$
public class ClientLoginModule implements LoginModule {
@Override
public void initialize(Subject subject,
CallbackHandler callbackHandler,
Map<String, ?> sharedState,
Map<String, ?> options) {
this.mSubject = subject;
this.mCallback = callbackHandler;
}
@Override
public boolean login() throws LoginException {
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback(Messages.PROMPT_USERNAME.getText());
callbacks[1] = new PasswordCallback(Messages.PROMPT_PASSWORD.getText(),false);
try {
mCallback.handle(callbacks);
} catch (UnsupportedCallbackException e) {
final LoginException ex = new FailedLoginException(e.getMessage());
ex.initCause(e);
throw ex;
} catch (IOException e) {
final LoginException ex = new FailedLoginException(e.getMessage());
ex.initCause(e);
throw ex;
}
mUsername = ((NameCallback)callbacks[0]).getName();
if(mUsername == null || mUsername.trim().length() == 0) {
throw new AccountNotFoundException(Messages.EMPTY_USERNAME.getText());
}
char [] password = ((PasswordCallback)callbacks[1]).getPassword();
try {
if(!ClientLoginHelper.isValidCredentials(mUsername, password)) {
Messages.USER_LOGIN_ERROR_LOG.warn(this, mUsername);
throw new FailedLoginException(
Messages.USER_LOGIN_FAIL.getText(mUsername));
}
} catch (ClientInitException e) {
Messages.USER_LOGIN_ERROR_LOG.warn(this,e, mUsername);
LoginException exception = new FailedLoginException(
Messages.USER_LOGIN_ERROR.getText());
exception.initCause(e);
throw exception;
}
SLF4JLoggerProxy.debug(this,"login done for user {}", mUsername); //$NON-NLS-1$
return true;
}
@Override
public boolean commit() throws LoginException {
mPrincipals.add(new UserPrincipal(mUsername));
mSubject.getPrincipals().addAll(mPrincipals);
Messages.USER_LOGIN_LOG.info(this, mUsername);
return true;
}
@Override
public boolean abort() throws LoginException {
SLF4JLoggerProxy.debug(this,"Aborting login for user {}", mUsername); //$NON-NLS-1$
clear();
return true;
}
@Override
public boolean logout() throws LoginException {
mSubject.getPrincipals().removeAll(mPrincipals);
mPrincipals.clear();
Messages.USER_LOGOUT_LOG.info(this, mUsername);
clear();
return true;
}
private void clear() {
mUsername = null;
}
private Subject mSubject;
private CallbackHandler mCallback;
private Set<Principal> mPrincipals = new HashSet<Principal>();
private String mUsername;
}