Stuart,
I have been unable to go through this thread in greater detail (that is
required). I am planning to do it today.
I do not question the assertion that authentication mechanisms should
have access to credentials. The challenge for me is when we use
IdentityManager
for everything (including credentials). As Shane pointed out, users
will just
expose IM directly.
Pedro and I were discussing maybe we should split the responsibilities
of IdentityManager.
Credential Management is a separate concern that should not be dealt by
users of the IdentityManager
API. CM would be a concern of authentication mechanisms. Thoughts?
Regards,
Anil
On 05/01/2013 08:57 PM, Stuart Douglas wrote:
The IDM is a user data store, and part of that user data is
credentials.
At some point you have to let authentication mechanisms get access to
them (I know for some simple auth methods like a hashed password this is
not the case as you can just query the backing store using the provided
credential to see if they match, but we should not be designing for the
simplest case).
The CredentialHandler method still allows you to query the credentials,
just in a more round about way. So far you have not given a single
example where the retrieveCurrentCredential() method would allow access
to a user credential, that the CredentialHandler technique would not.
Can you give me any scenarios where this approach increases security, as
this seems to be the premise that your argument is based on?
IMHO the ability to retrieve a credential is a IDM operation, but once
you also add credential validation it becomes an authentication manager
as well (as I believe Darran has already said).
Using the credential to pass state around is also very problematic, as
there could be multiple different mechanisms that wish to use the same
credential in different ways, which would mean that the credential would
need to have mutable fields for all the different state these mechanisms
need.
I just think this approach will cause problems for the advanced cases,
and does not provide any additional security. For digest this is the
difference between the digest handler just grabbing the credential it
needs and using it directly, vs registering a callback handler, and
using the callback handler to expose information about the stored
credential using mechanism specific fields in the credential.
Also if another mechanism such as SASL is also using the same
credentials it gets even more problematic. Do we need two different
versions of the same credential stored per user, one for each
implementation of CredentialHandler, or are we going to have some way of
stacking credential handlers, and we just have to make sure the
credential has implementation specific fields for each handler (and just
hope that no third party wants to use the same credential classes with
different state).
I'm sure we could hack around all these problems, and I must admit I
have not spent nearly as much time working on this as you guys, but it
just seems like this approach will make it more difficult to extend the
available authentication mechanisms than it needs to be.
Stuart
Anil Saldhana wrote:
> Shane - you can add the API for this. But I would like to think about it further. I
really do not like creds via IM interface.
>
> On May 1, 2013, at 7:33 PM, Shane Bryzak<sbryzak(a)redhat.com> wrote:
>
>> Bill, I'm going to concede defeat on this one, so congrats on a
>> well-fought victory ;) The one saving grace with the IdentityManager is
>> that in an EE environment it is actually wrapped by a
>> SecuredIdentityManager, which allows for permission checks to be defined
>> for every single IDM operation. With this in mind, it should be trivial
>> to implement a permission check for credential retrieval that restricts
>> it to only allow the reading of credentials for the currently
>> authenticated user (or whatever other permission logic the developer wants).
>>
>> So, with that in mind I propose the following additional methods for
>> IdentityManager:
>>
>> <T extends CredentialStorage> T retrieveCurrentCredential(Agent
>> agent, Class<T> storageClass);
>> <T extends CredentialStorage> List<T>
retrieveCredentials(Agent
>> agent, Class<T> storageClass);
>>
>> These will essentially delegate to the underlying CredentialStore, and
>> if there is none (which will be the case in an LDAP-only configuration)
>> you'll get an OperationNotSupportedException.
>>
>> Will this be sufficient for your requirements?
>>
>> Shane