import javax.security.auth.*; import javax.security.auth.spi.*; import javax.security.auth.callback.*; import javax.security.auth.login.*; import java.security.Principal; import java.io.*; import java.util.*; /** * Login module que comprueba usuario y password. */ public class PasswordLoginModule implements LoginModule { private Subject mSujeto; private CallbackHandler mCallbackHandler; private boolean mLoginExito = false; private boolean mCommitExito = false; private String mUsuario; private char[] mPassword; private Principal mPrincipal; /** * Inicializar. */ public void initialize(Subject sujeto,CallbackHandler callbackHandler, Map estadoCompartido,Map opciones) { mSujeto = sujeto; mCallbackHandler = callbackHandler; mLoginExito = false; mCommitExito = false; mUsuario = null; clearPassword(); } /** * Intentar login. * * usuario: "sco" * password: "scosco" */ public boolean login() throws LoginException { if (mCallbackHandler == null) { throw new LoginException("CallbackHandler no definido"); } // Crear dos callbacks: uno para usuario y el otro para password. Callback[] callbacks = new Callback[2]; callbacks[0] = new NameCallback("Usuario"); callbacks[1] = new PasswordCallback("Password", false); try { // Llamar al callbackhandler para rellenar informacion mCallbackHandler.handle(callbacks); mUsuario = ((NameCallback)callbacks[0]).getName(); char[] tempPassword = ((PasswordCallback)callbacks[1]).getPassword(); mPassword = new char[tempPassword.length]; System.arraycopy(tempPassword, 0, mPassword, 0, tempPassword.length); // Borrar password en el callback ((PasswordCallback)callbacks[1]).clearPassword(); } catch (IOException ioe) { throw new LoginException(ioe.toString()); } catch (UnsupportedCallbackException uce) { throw new LoginException(uce.toString()); } // Validar usuario y password if ( "sco".equals(mUsuario) && mPassword.length == 6 && mPassword[0] == 's' && mPassword[1] == 'c' && mPassword[2] == 'o' && mPassword[3] == 's' && mPassword[4] == 'c' && mPassword[5] == 'o' ) { // Usuario y password son correctos mLoginExito = true; return true; } else { // Fallo de autentificación. Borrar estado y lanzar excepción mLoginExito = false; mUsuario = null; clearPassword(); throw new FailedLoginException("Password Incorrecto"); } } /* * Llamar si el login tiene éxito */ public boolean commit() throws LoginException { if (mLoginExito == false) { return false; } // Login con éxito: crear Principal y añadirlo al Subject mPrincipal = new ImplPrincipal(mUsuario); if (!(mSujeto.getPrincipals().contains(mPrincipal))) { mSujeto.getPrincipals().add(mPrincipal); } // Si queremos que el Subject contenga credenciales // este es el momento para añadirlas. // Borrar usuario y password. mUsuario = null; clearPassword(); mCommitExito = true; return true; } /** * Llamar si el login falla */ public boolean abort() throws LoginException { // Si login falla, devolver false if (mLoginExito == false) { return false; } else if (mLoginExito == true && mCommitExito == false) { // Nuestro login tuvo éxito pero otros fallaron mLoginExito = false; mUsuario = null; clearPassword(); mPrincipal = null; } else { // Nosotros hicimos commit pero alguien falló logout(); } return true; } /** * Logout */ public boolean logout() throws LoginException { // Borrar principal del usuario mSujeto.getPrincipals().remove(mPrincipal); mLoginExito = false; mCommitExito = false; mUsuario = null; clearPassword(); mPrincipal = null; return true; } /** * Borrar el password */ private void clearPassword() { if (mPassword == null) { return; } for (int i=0;i