users@javaee-security-spec.java.net

[javaee-security-spec users] [jsr375-experts] Fwd: Updated Multi IdentityStore Proposal

From: Rudy De Busscher <rdebusscher_at_gmail.com>
Date: Sun, 4 Sep 2016 20:08:26 +0200

Hi all,

This is the updated multi IdentityStore based on earlier feedback on this
mailing list.


*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.

*IdentityStore interface*

* CredentialValidationResult validate(Credential credential,
CallerPrincipal callerPrincipal);*

* default int priority() {*
* return 100;*
* }*

* default ValidationType validationType() {*
* return ValidationType.BOTH;*
* }*

*validate method*

the CallerPrincipal parameter contains previous validated Caller
information (authentication) if any. Value can be null.

*ValidationType method*

ValidationType contains meta information for the IdentityStore handler. It
defines if the store does authentication only (ValidationType.AUTHENTICATION),
authorization only (ValidationType.AUTHORIZATION) or both; the default.
This information is used by the handler to define if the store should be
called. For example, the default IdentityStore handler does not call a
store who does Authorization only when no successful authentication took
place.

*priority method *

determines the order in the case when there are multiple ones. They are
ordered by ascending values, meaning that the IdentityStore with the lowest
value is processed first.

*Status rules*

Stores should return the following Status (contained in the
CredentialValidationResult result parameter)
*NOT_VALIDATED*: Type of Credential isn't compatible with the ones expected
by the store.
*INVALID* : In case the store does Authentication, the validation of the
credential failed.
*AUTHENTICATED* : In case the store does Authentication only and the
validation succeeded.
*VALID* : In case the store does Authorization and groups are supplied for
the Caller (can be an empty list indicating no groups assigned to caller)

So When Store does handle both (Authentication and Authorization) it should
return NOT_VALIDATED, INVALID or VALID
In case store does Authentication only; it is NOT_VALIDATED, INVALID or
AUTHENTICATED
In case store does Authorization only; it is NOT_VALIDATED or VALID (the
assumption is that when store can handle the type of Credentials, the

*IdentityStore Handler *

Default IdentityStore Handler uses the following algorithm
1) Order all identityStores based on the priority value
2) Loop over all IdentityStores unless one of the stores return the status
INVALID
3) Call a certain IdentityStore when
   * The Store does Authentication, regardless of the result of the calls
to previous IdentityStores.
   * The Store does Authorization only and another Store already successful
validated the Credentials (Result is AUTHENTICATED or VALID)
4) The result of the call to the IdentityStore is combined with 'previous'
result of the there calls to the IdentityStores.
   * Groups are added to the already defined groups of the caller.

*Issues*

The current default IdentityStore Handler handler can't handle this use case
- Caller can be authenticated by one IdentityStore (for example LDAP or
Database)

This is because the loop stops when an INVALID result is returned by a
IdentityStore. This is required to veto another successful authentication
like in this use case
- The first IdentityStore based on OAuth2 allows any Google account, but
the second store limits the access to a certain google domain.

So probably we need some configuration to be able to combine both use cases
in one algorithm.

*Code status*

The current code needs probably some more tests and verification. I try to
write them in the following weeks.

Changes for this updated proposal can be viewed in this commit
https://github.com/rdebusscher/soteria/commit/afa4cecf626266d0ae400f806b0358
ed7b07bc61
And are added to the first pull request to the Soteria repository.

Best regards
Rudy