jsr375-experts@javaee-security-spec.java.net

[jsr375-experts] Multi IdentityStore proposal

From: Rudy De Busscher <rdebusscher_at_gmail.com>
Date: Sat, 13 Aug 2016 14:24:03 +0200

Hi all,

I have put together the text around my idea of the multi IdentityStore.

The code is not yet completely ready and is missing an example and test.
I'll try to create that in the next few days and make a pull request at
that time.

*Multiple IdentityStore proposal*

*Why multiple stores?*
There are various use cases where multiple identity stores can be useful.
And it allows us to decouple the authentication and authorization parts of
the current mechanism. So that groups can be retrieved by another store
then the credential checking.

*Examples*
* When your application should allow users which are defined in multiple
stores, like an LDAP for your internal users and a Database store for the
external ones.
* Users are authenticated by an OAuth2 provider and the groups are
retrieved from a database table.
* The first IdentityStore based on OAuth2 allows any Google account, but
the second store limits the access to a certain google domain.

*Technical changes*
* When multiple stores are allowed, we need another interface which can be
injected into the AuthenticationMechanism.
Proposal : *IdentityStoreHandler* which has the same signature as the
IdentityStore.

* IdentityStore interface receives a new method which determines the order
of the IdentityStores when there are multiple ones.
*int priority();*

* The current **Definition annotations are extended by a member which is
transferred to the priority value of the IdentityStore.

* The *ValidationResult.Status enum* is extended with some constants.
Values and meanings are

        *NONE* : The default status, indicating that no IdentityStore has
been consulted yet.

        *AUTHENTICATED* : Indicates that the credential is validated but
that no Groups are assigned yet.

        *NOT_VALIDATED* : Indicates that the credential could not be
validated

        *INVALID* : Indicates that the credential is not valid after a
validation attempt.

        *VALID* : Indicates that the credential is valid after a validation
attempt and Groups are assigned.

* IdentityStores are *ordered by ascending values of the priority value*.
This means that the IdentityStore with the lowest value is processed first.
see next bullet.

* The default IdentityStoreHandler follows this algorithm when the
validate() method is called:
     - *Loop over all stores*, in order of the priority value, until
ValidationResult.Status is INVALID or loop is terminated.
     - At the end of the loop, change the status in following cases
         * NONE -> INVALID
         * AUTHENTICATED -> VALID

* The IdentityStores logic is
     - If the store decides to do *authentication logic* (a store can also
decide to perform only the logic in the case the Status is NONE or
NOT_VALIDATED, meaning the user is not authenticated yet) it should set the
status to
          + *NOT_VALIDATED* : When credentials could not be validated
(should not set this Status when the Status was already AUTHENTICATED or
VALID)
          + *AUTHENTICATED* : When credentials are valid but the store
didn't assign any groups (Should not set this status when the original
Status was VALID)
          + *INVALID* : Credentials are not valid and the store is allowed
to veto another authentication by another IdentityStore.
          + *VALID* : When credentials are valid and the store did assign
groups (which can be the empty set)

     - The IdentityStore can decide that only *authorization* is performed,
and should only do this in the case where Status has the value
AUTHENTICATED or VALID.
When the store adds Groups, it should change the Status to VALID.

Best regards
Rudy