geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Jencks <djen...@gluecode.com>
Subject Re: svn commit: r154075 - in geronimo/trunk/modules/security/src: java/org/apache/geronimo/security/jaas/UPCredentialLoginModule.java java/org/apache/geronimo/security/jaas/UsernamePasswordCredential.java test/org/apache/geronimo/security/jaas/ConfigurationEntryTest.java
Date Thu, 17 Feb 2005 19:45:40 GMT
There are a couple problems with this:

1. it essentially duplicates the intended functionality of the existing  
o.a.g.security.realm.GeronimoPasswordCredential/LoginModule

2. The inclusion of the destroy method and implementation breaks the  
contracts for equals and hashcode for use in a Collection.  In other  
words, after destroying UserPasswordCredential you won't be able to  
remove it from a collection.  I think throwing an IllegalStateException  
from equals and hashcode after destroy might be reasonable.  Currently,  
calling hashCode after destroy will have undesirable effects (npe)

I propose we fix the equals/hashcode problem somehow and replace the  
use of GeronimoPasswordCredential[LoginModule] with the new classes.

thanks
david jencks

On Feb 16, 2005, at 11:48 AM, adc@apache.org wrote:

> Author: adc
> Date: Wed Feb 16 11:48:03 2005
> New Revision: 154075
>
> URL: http://svn.apache.org/viewcvs?view=rev&rev=154075
> Log:
> Simple login module that scrapes the username/password and places the  
> information into a private credential.
>
> Added:
>      
> geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/ 
> jaas/UPCredentialLoginModule.java
>      
> geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/ 
> jaas/UsernamePasswordCredential.java
> Modified:
>      
> geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/ 
> jaas/ConfigurationEntryTest.java
>
> Added:  
> geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/ 
> jaas/UPCredentialLoginModule.java
> URL:  
> http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/ 
> java/org/apache/geronimo/security/jaas/UPCredentialLoginModule.java? 
> view=auto&rev=154075
> ======================================================================= 
> =======
> ---  
> geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/ 
> jaas/UPCredentialLoginModule.java (added)
> +++  
> geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/ 
> jaas/UPCredentialLoginModule.java Wed Feb 16 11:48:03 2005
> @@ -0,0 +1,108 @@
> +/**
> + *
> + * Copyright 2005 The Apache Software Foundation
> + *
> + *  Licensed under the Apache License, Version 2.0 (the "License");
> + *  you may not use this file except in compliance with the License.
> + *  You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + *  Unless required by applicable law or agreed to in writing,  
> software
> + *  distributed under the License is distributed on an "AS IS" BASIS,
> + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or  
> implied.
> + *  See the License for the specific language governing permissions  
> and
> + *  limitations under the License.
> + */
> +package org.apache.geronimo.security.jaas;
> +
> +import java.io.IOException;
> +import java.util.Map;
> +import java.util.Set;
> +import javax.security.auth.Subject;
> +import javax.security.auth.callback.Callback;
> +import javax.security.auth.callback.CallbackHandler;
> +import javax.security.auth.callback.NameCallback;
> +import javax.security.auth.callback.PasswordCallback;
> +import javax.security.auth.callback.UnsupportedCallbackException;
> +import javax.security.auth.login.LoginException;
> +import javax.security.auth.spi.LoginModule;
> +
> +
> +/**
> + * Inserts Username/Password credential into private credentials of  
> Subject.
> + * <p/>
> + * If either the username or password is not passed in the callback  
> handler,
> + * then the credential is not placed into the Subject.
> + *
> + * @version $Revision: $ $Date: $
> + */
> +public class UPCredentialLoginModule implements LoginModule {
> +
> +    private Subject subject;
> +    private CallbackHandler callbackHandler;
> +    private UsernamePasswordCredential upCredential;
> +
> +    public boolean abort() throws LoginException {
> +
> +        return logout();
> +    }
> +
> +    public boolean commit() throws LoginException {
> +
> +        if (subject.isReadOnly()) {
> +            throw new LoginException("Subject is ReadOnly");
> +        }
> +
> +        Set pvtCreds = subject.getPrivateCredentials();
> +        if (upCredential != null && !pvtCreds.contains(upCredential))  
> {
> +            pvtCreds.add(upCredential);
> +        }
> +
> +        return true;
> +    }
> +
> +    public boolean login() throws LoginException {
> +
> +        Callback[] callbacks = new Callback[2];
> +
> +        callbacks[0] = new NameCallback("User name");
> +        callbacks[1] = new PasswordCallback("Password", false);
> +        try {
> +            callbackHandler.handle(callbacks);
> +        } catch (IOException ioe) {
> +            throw (LoginException) new  
> LoginException().initCause(ioe);
> +        } catch (UnsupportedCallbackException uce) {
> +            throw (LoginException) new  
> LoginException().initCause(uce);
> +        }
> +
> +        String username = ((NameCallback) callbacks[0]).getName();
> +        char[] password = ((PasswordCallback)  
> callbacks[1]).getPassword();
> +
> +        if (username == null || password == null) return true;
> +
> +        upCredential = new UsernamePasswordCredential(username, new  
> String(password));
> +
> +        return true;
> +    }
> +
> +    public boolean logout() throws LoginException {
> +
> +        if (upCredential == null) return true;
> +
> +        Set pvtCreds =  
> subject.getPrivateCredentials(UsernamePasswordCredential.class);
> +        if (pvtCreds.contains(upCredential)) {
> +            pvtCreds.remove(upCredential);
> +        }
> +
> +        upCredential = null;
> +
> +        return true;
> +    }
> +
> +    public void initialize(Subject subject, CallbackHandler  
> callbackHandler, Map sharedState, Map options) {
> +
> +        this.subject = subject;
> +        this.callbackHandler = callbackHandler;
> +    }
> +}
>
> Added:  
> geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/ 
> jaas/UsernamePasswordCredential.java
> URL:  
> http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/ 
> java/org/apache/geronimo/security/jaas/ 
> UsernamePasswordCredential.java?view=auto&rev=154075
> ======================================================================= 
> =======
> ---  
> geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/ 
> jaas/UsernamePasswordCredential.java (added)
> +++  
> geronimo/trunk/modules/security/src/java/org/apache/geronimo/security/ 
> jaas/UsernamePasswordCredential.java Wed Feb 16 11:48:03 2005
> @@ -0,0 +1,91 @@
> +/**
> + *
> + * Copyright 2005 The Apache Software Foundation
> + *
> + *  Licensed under the Apache License, Version 2.0 (the "License");
> + *  you may not use this file except in compliance with the License.
> + *  You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + *  Unless required by applicable law or agreed to in writing,  
> software
> + *  distributed under the License is distributed on an "AS IS" BASIS,
> + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or  
> implied.
> + *  See the License for the specific language governing permissions  
> and
> + *  limitations under the License.
> + */
> +package org.apache.geronimo.security.jaas;
> +
> +import java.io.Serializable;
> +import javax.security.auth.DestroyFailedException;
> +import javax.security.auth.Destroyable;
> +import javax.security.auth.RefreshFailedException;
> +import javax.security.auth.Refreshable;
> +
> +
> +/**
> + * A username/password credential.  Used to store the  
> username/password in the
> + * Subject's private credentials.
> + *
> + * @version $Revision: $ $Date: $
> + */
> +public class UsernamePasswordCredential implements Destroyable,  
> Refreshable, Serializable {
> +
> +    private String username;
> +    private String password;
> +    private boolean destroyed;
> +
> +    public UsernamePasswordCredential(String username, String  
> password) {
> +        assert username != null;
> +        assert password != null;
> +
> +        this.username = username;
> +        this.password = password;
> +    }
> +
> +    public String getUsername() {
> +        return username;
> +    }
> +
> +    public String getPassword() {
> +        return password;
> +    }
> +
> +    public void destroy() throws DestroyFailedException {
> +        username = null;
> +        password = null;
> +        destroyed = true;
> +    }
> +
> +    public boolean isDestroyed() {
> +        return destroyed;
> +    }
> +
> +    public void refresh() throws RefreshFailedException {
> +    }
> +
> +    public boolean isCurrent() {
> +        return !destroyed;
> +    }
> +
> +    public boolean equals(Object o) {
> +        if (this == o) return true;
> +        if (!(o instanceof UsernamePasswordCredential)) return false;
> +
> +        final UsernamePasswordCredential usernamePasswordCredential =  
> (UsernamePasswordCredential) o;
> +
> +        if (destroyed != usernamePasswordCredential.destroyed) return  
> false;
> +        if (!password.equals(usernamePasswordCredential.password))  
> return false;
> +        if (!username.equals(usernamePasswordCredential.username))  
> return false;
> +
> +        return true;
> +    }
> +
> +    public int hashCode() {
> +        int result;
> +        result = username.hashCode();
> +        result = 29 * result + password.hashCode();
> +        result = 29 * result + (destroyed ? 1 : 0);
> +        return result;
> +    }
> +}
>
> Modified:  
> geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/ 
> jaas/ConfigurationEntryTest.java
> URL:  
> http://svn.apache.org/viewcvs/geronimo/trunk/modules/security/src/ 
> test/org/apache/geronimo/security/jaas/ConfigurationEntryTest.java? 
> view=diff&r1=154074&r2=154075
> ======================================================================= 
> =======
> ---  
> geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/ 
> jaas/ConfigurationEntryTest.java (original)
> +++  
> geronimo/trunk/modules/security/src/test/org/apache/geronimo/security/ 
> jaas/ConfigurationEntryTest.java Wed Feb 16 11:48:03 2005
> @@ -48,6 +48,7 @@
>      protected ObjectName loginConfiguration;
>      protected ObjectName loginService;
>      protected ObjectName clientCE;
> +    protected ObjectName testUPCred;
>      protected ObjectName testCE;
>      protected ObjectName testRealm;
>      protected ObjectName serverStub;
> @@ -79,6 +80,7 @@
>          assertTrue("server subject should be associated with remote  
> id", ContextManager.getRegisteredSubject(remote.getId()) != null);
>          assertTrue("server subject should have two realm principals  
> ("+subject.getPrincipals(RealmPrincipal.class).size()+")",  
> subject.getPrincipals(RealmPrincipal.class).size() == 2);
>          assertTrue("server subject should have five principals  
> ("+subject.getPrincipals().size()+")", subject.getPrincipals().size()  
> == 5);
> +        assertTrue("server subject should have one private credential  
> ("+subject.getPrivateCredentials().size()+")",  
> subject.getPrivateCredentials().size() == 1);
>          RealmPrincipal principal = (RealmPrincipal)  
> subject.getPrincipals(RealmPrincipal.class).iterator().next();
>          assertTrue("id of principal should be non-zero",  
> principal.getId() != 0);
>
> @@ -108,6 +110,7 @@
>          assertTrue("server subject should be associated with remote  
> id", ContextManager.getRegisteredSubject(remote.getId()) != null);
>          assertTrue("server subject should have two realm principals  
> ("+subject.getPrincipals(RealmPrincipal.class).size()+")",  
> subject.getPrincipals(RealmPrincipal.class).size() == 2);
>          assertTrue("server subject should have five principals  
> ("+subject.getPrincipals().size()+")", subject.getPrincipals().size()  
> == 5);
> +        assertTrue("server subject should have one private credential  
> ("+subject.getPrivateCredentials().size()+")",  
> subject.getPrivateCredentials().size() == 1);
>          principal = (RealmPrincipal)  
> subject.getPrincipals(RealmPrincipal.class).iterator().next();
>          assertTrue("id of principal should be non-zero",  
> principal.getId() != 0);
>
> @@ -166,6 +169,13 @@
>          kernel.loadGBean(testCE, gbean);
>
>          gbean = new  
> GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
> +        testUPCred = new  
> ObjectName("geronimo.security:type=LoginModule,name=UPCred");
> +        gbean.setAttribute("loginModuleClass",  
> "org.apache.geronimo.security.jaas.UPCredentialLoginModule");
> +        gbean.setAttribute("serverSide", new Boolean(true));
> +        gbean.setAttribute("options", new Properties());
> +        kernel.loadGBean(testUPCred, gbean);
> +
> +        gbean = new  
> GBeanMBean("org.apache.geronimo.security.jaas.LoginModuleGBean");
>          testCE = new  
> ObjectName("geronimo.security:type=LoginModule,name=audit");
>          gbean.setAttribute("loginModuleClass",  
> "org.apache.geronimo.security.realm.providers.FileAuditLoginModule");
>          gbean.setAttribute("serverSide", new Boolean(true));
> @@ -178,7 +188,8 @@
>          testRealm = new  
> ObjectName("geronimo.security:type=SecurityRealm,realm=properties- 
> realm");
>          gbean.setAttribute("realmName", "properties-realm");
>          props = new Properties();
> -         
> props.setProperty("LoginModule.2.OPTIONAL","geronimo.security: 
> type=LoginModule,name=audit");
> +         
> props.setProperty("LoginModule.3.REQUIRED","geronimo.security: 
> type=LoginModule,name=UPCred");
> +         
> props.setProperty("LoginModule.2.REQUIRED","geronimo.security: 
> type=LoginModule,name=audit");
>           
> props.setProperty("LoginModule.1.REQUIRED","geronimo.security: 
> type=LoginModule,name=properties");
>          gbean.setAttribute("loginModuleConfiguration", props);
>          gbean.setReferencePatterns("ServerInfo",  
> Collections.singleton(serverInfo));
> @@ -194,6 +205,7 @@
>          kernel.startGBean(loginService);
>          kernel.startGBean(clientCE);
>          kernel.startGBean(testCE);
> +        kernel.startGBean(testUPCred);
>          kernel.startGBean(testRealm);
>          kernel.startGBean(serverStub);
>      }
> @@ -201,6 +213,7 @@
>      protected void tearDown() throws Exception {
>          kernel.stopGBean(serverStub);
>          kernel.stopGBean(testRealm);
> +        kernel.stopGBean(testUPCred);
>          kernel.stopGBean(testCE);
>          kernel.stopGBean(clientCE);
>          kernel.stopGBean(loginService);
> @@ -209,6 +222,7 @@
>
>          kernel.unloadGBean(loginService);
>          kernel.unloadGBean(testCE);
> +        kernel.unloadGBean(testUPCred);
>          kernel.unloadGBean(testRealm);
>          kernel.unloadGBean(clientCE);
>          kernel.unloadGBean(serverStub);
>
>


Mime
View raw message