Hi,

While I would argue along the same lines as Marcel, your proposal is quote appealing ...

So, as much as I would probably prefer to reuse existing API (namely UserAdmin), for then purpose of the WebConsole this might be sufficient.

Regards
Felix

Guillaume Nodet schrieb:
I don't think having a UserAdmin delegating to JAAS could work because
JAAS does not provide anything about modifying the underlying storage
for creating / removing users or groups.   UserAdmin provides such
features, so I think it has to be to other way around: it should be
quite easy to implement a JAAS login module that delegates to
UserAdmin.
Given I don't think requiring JAAS is a good idea, that's why I
proposed such a simple API.
I don't really see any drawback to such a pluggable mechanism, as I
think it can be implemented for both JAAS and UserAdmin in a few lines
of code:

public class UserAdminProvider implements WebConsoleSecurityProvider {
   private UserAdmin userAdmin;
   private String userProperty;
   private String credProperty;
   public class UserAdminProvider(UserAdmin userAdmin, String
userProperty, String credProperty) {
      this.userAdmin = userAdmin;
      this.userProperty = userProperty;
      this.credProperty = credProperty;
   }
   public Object authenticate(String username, Object credential)
throws SecurityException {
      User user = userAdmin.getUser(userProperty, userName);
      if (user == null) throw new SecurityException("No such user");
      if (!user.hasCredential(credProperty, credential)) throw new
SecurityException("Bad credential");
      return user;
   }
   public void authorize(Object user, String role) throws SecurityException {
      Authorization auth = userAdmin.getAuthorization((User) user);
      if (!auth.hasRole(role)) throw new SecurityException("Not authorized");
   }
}


public class JAASProvider implements WebConsoleSecurityProvider {
   private String domain;
   public JAASProvider(String domain) {
      this.domain = domain;
   }
   public Object authenticate(String username, Object credential)
throws SecurityException {
        Subject subject = new Subject();
        LoginContext loginContext = new LoginContext(domain, subject,
new CallbackHandler() {
            public void handle(Callback[] callbacks) throws
IOException, UnsupportedCallbackException {
                for (int i = 0; i < callbacks.length; i++) {
                    if (callbacks[i] instanceof NameCallback) {
                        ((NameCallback) callbacks[i]).setName(username);
                    } else if (callbacks[i] instanceof
PasswordCallback && credentials instanceof String) {
                        ((PasswordCallback)
callbacks[i]).setPassword(((String) credential).toCharArray());
                    } else if (callbacks[i] instanceof
CertificateCallback && credentials instanceof X509Certificate) {
                        ((CertificateCallback)
callbacks[i]).setCertificate((X509Certificate) credential);
                    } else {
                        throw new UnsupportedCallbackException(callbacks[i]);
                    }
                }
            }
        });
        loginContext.login();
        return subject;
   }
   public void authorize(Object user, String role) throws SecurityException {
      if (!((Subject) user).getPrincipals().contains(new
GroupPrincipal(role))) throw new SecurityException("Not authorized");
   }
}

Pluggability / extensibility is always a good thing imho, as long as
it's not overengineered, which is not the case here imho.

On Wed, May 27, 2009 at 11:31, Marcel Offermans
<[email protected]> wrote:
Hello Guillaume,

On May 27, 2009, at 11:20 , Guillaume Nodet wrote:

Right, I think there is a real need to support UserAdmin, but given
both JAAS and UserAdmin will be used for the same thing, it should be
easy to support both using a simple interface:

 public interface WebConsoleSecurityProvider {
    /** Check if the user with the specified password exists and
return an object identifying the user, else throw an exception */
    public Object authenticate(String username, String password)
throws SecurityException;
    /** Check that the authenticated user has the given role
permission or throw an exception */
    public void authorize(Object user, String role) throws
SecurityException;
 }

Imho, this should be sufficient to provide authentication and
authorization for the web console and can be easily implemented using
UserAdmin or JAAS.
To be honest, UserAdmin already is an interface which abstracts from an
implementation, so I don't really see a need to add another interface to
abstract from that. Having a JAAS backend for UserAdmin would be nice too
since that would be usable in a much broader context.

Greetings, Marcel





Reply via email to