[security-dev] Credentials API redesign

Shane Bryzak sbryzak at redhat.com
Thu Dec 6 02:21:45 EST 2012

On 12/06/2012 01:50 PM, Anil Saldhana wrote:
> Comments are inline.  Also we need to be thinking about:
> a) combined authentication mechanisms.

This is already supported by the design.

> b) session management.

I'm assuming you mean token-based authentication?  We could either 
support this via the credentials api, or as a separate feature altogether.

> On 12/05/2012 08:18 PM, Shane Bryzak wrote:
>> Hey guys,
>> I've completed the first round of redesigns for the credentials API
>> based on the feedback provided by Darran and others.  It might require
>> some minimal tweaking to address a couple of minor edge cases, however
>> at this point in time I'd like to run through the basic design to see
>> what you guys think.  Up front I must say that it's more complex than I
>> had hoped, however after analysing all the use cases I feel that the
>> complexity is a necessity for providing a truly robust, extensible API.
>> To try and present this in a logical manner, I'm going to describe the
>> credentials API in terms of the chronological order of events during the
>> authentication process.  To start with, let's take a look at the
>> LoginCredentials interface:
>> public interface LoginCredentials {
>>        void invalidate();
>> }
> invalidate() can be called clear()?

I kind of prefer invalidate() because it might not necessarily clear all 
the state, which I believe is what clear() would imply.  An example 
would be username/password authentication - if a user logs in with an 
invalid password you would only want to clear their password state, but 
not the username state.

>> Implementations of this interface are intended to contain the state
>> provided by the user in order to carry out authentication.  While the
>> Credential interface is designed to represent an atomic credential value
>> (such as a password, certificate, or biometric data such as a
>> fingerprint), LoginCredentials is designed to encapsulate the credential
>> value with additional state required by the authentication process.
>> Let's take a look at an implementation supporting the most common form
>> of credentials, a username and password:
>> public class UsernamePasswordCredentials implements LoginCredentials {
>>        private String username;
>>        private PasswordCredential password;
>>        public String getUsername() {
>>            return username;
>>        }
>>        public void setUsername(String username) {
>>            this.username = username;
>>        }
>>        public PasswordCredential getPassword() {
>>            return password;
>>        }
>>        public void setPassword(PasswordCredential password) {
>>            this.password = password;
>>        }
>>        @Override
>>        public void invalidate() {
>>            username = null;
>>            password.clear();
>>        }
>> }
>> This implementation provides the capability for setting a username
>> (represented as a String) and a PasswordCredential.  Other
>> implementations are free to define whichever properties they require,
>> for example a CertificateCredentials class may simply contain an
>> X509CertificateCredential and nothing else.
>> Once the user provides their credentials, the LoginCredentials instance
>> can be passed to IdentityManager via the following method:
>> public interface IdentityManager {
>>        User validateCredentials(LoginCredentials credentials);
>> }
>> To handle the actual processing of the credentials and perform whatever
>> business logic is required to authenticate the user, the following SPI
>> interface is used:
>> public interface CredentialHandler {
>>        User validate(LoginCredentials credentials, IdentityStore store);
>>        void update(User user, Credential credential, IdentityStore store);
>> }
> The credential validation/updation should be an implementation strategy of
> the IdentityStore implementation rather than the IdentityManager.
The CredentialHandler SPI is an implementation strategy of neither. It's 
a standalone SPI that decouples credential validation from the 
IdentityStore (important because there is no one size fits all) and 
provides a pluggable mechanism for developers to provide their own 
credential validation logic.  If you're actually referring to the fact 
that the CredentialHandlerFactory is provided by the 
IdentityConfiguration (which in turn is "held" by the IdentityManager) 
then I guess we could invert the lookup so that it is done from the 
IdentityStore instead, probably via the IdentityStoreInvocationContext.

> In the case of LDAP servers, they never store user password in the clear
> but have
> some form of hashing/salting etc. The LDAPIdentityStore implementation
> always provides
> the ldap server with the clear text password and the ldap server uses
> its internal strategies to
> convert the clear text password into some hash etc and validates with
> the store value.
> I think the same strategy can be used by the JPA implementation. The
> IdentityManager passes it
> the clear text password to the IS implementation.  Based on pluggable
> credential handling strategies
> at the IdentityStore implementation, computations are performed on the
> passed credential and validated/updated
> in the underlying data store.
> In Darran's use case of (username + hash + realmname), the underlying
> store needs to store one value that
> is a combination of (hash + realmname).  Now the IdentityManager will
> pass to the IdentityStore the string (hash+realm),
> now Darran's plugged handlers at the IdentityStore implementation will
> convert this into some form that matches with
> the stored value in the DB/LDAP.

All three of these use cases are readily supported by the design, and 
are essentially implementation details.

More information about the security-dev mailing list