users@javaee-security-spec.java.net

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

From: Rudy De Busscher <rdebusscher_at_gmail.com>
Date: Thu, 8 Sep 2016 20:00:23 +0200

Will this method be called (when for example no suitable overloaded method
is found). What should we advise the implementers to put in there? Always a
return NOT_VALIDATED status?

I'm not familiar with the technique presented to select a certain
overloaded method.

best regards
Rudy


On 8 September 2016 at 09:29, arjan tijms <arjan.tijms_at_gmail.com> wrote:

> Hi,
>
> The interface has the general "default CredentialValidationResult
> validate(Credential credential) { ... }" method.
>
> The store has to implement an overload for each credential type that it
> supports. Stepping away from multiple stores for a second, this means that
> the store will receive a different credential depending on which
> authentication mechanism it's used with. E.g. UsernamePasswordCredential
> for FORM, TokenCredential for StatelessJAXRS, X509Credential for DIGEST,
> etc.
>
> The implementors initially don't know about any of those parameters, but
> have to look up which actual credential types there are for any of those
> situations.
>
> Kind regards,
> Arjan Tijms
>
>
>
>
>
> On Thu, Sep 8, 2016 at 7:37 AM, Rudy De Busscher <rdebusscher_at_gmail.com>
> wrote:
>
>> Hi Arjan,
>>
>> It doesn't change the fact that an IdentityStore can receive a
>> UserNamePasswordCredential or AuthorizeOnlyCredential depending it is
>> used alone or in combination with another IdentityStore.
>>
>> And what validate() method will be defined in the interface (if any)?
>> Will it be clear for the implementers which parameter they should use (if
>> they don't read the spec)?
>>
>> Best regards
>> Rudy
>>
>>
>> On 7 September 2016 at 17:52, arjan tijms <arjan.tijms_at_gmail.com> wrote:
>>
>>> Hi everyone,
>>>
>>> I took another look at a way to remove the series of instance of casts,
>>> e.g.
>>>
>>> @Override
>>> public CredentialValidationResult validate(Credential credential) {
>>> if (credential instanceof UsernamePasswordCredential) {
>>> return validate((UsernamePasswordCredential) credential);
>>> }
>>>
>>> if (credential instanceof TokenCredential) {
>>> return validate((TokenCredential) credential);
>>> }
>>>
>>> if (credential instanceof CallerOnlyCredential) {
>>> return validate((CallerOnlyCredential) credential);
>>> }
>>>
>>> // etc for JWTCredential, StrongCryptCredential, ...
>>>
>>> return NOT_VALIDATED_RESULT;
>>> }
>>>
>>>
>>> With the help of my friend Jan Beernink we came up with the following
>>> initial solution for a default method in the IdentityStore interface:
>>>
>>>
>>> default CredentialValidationResult validate(Credential credential) {
>>> try {
>>> return CredentialValidationResult.class.cast(
>>> MethodHandles.lookup()
>>> .bind(this, "validate",
>>> methodType(CredentialValidationResult.class, credential.getClass()))
>>> .invoke(credential));
>>> } catch (Throwable e) {
>>> e.printStackTrace(); // tmp
>>> }
>>>
>>> return NOT_VALIDATED_RESULT;
>>> }
>>>
>>>
>>> This will find the right overloaded method automatically, so the checks
>>> and casts can be omitted and the store only has to implement the overloads.
>>> Some work needs to go into it still to prevent a recursive loop if no
>>> methods at all are defined in the class that implements Identitystore, but
>>> I think this is a good start.
>>>
>>> Rudy, does this take away some of your concerns?
>>>
>>> Kind regards,
>>> Arjan Tijms
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Tue, Sep 6, 2016 at 10:49 PM, arjan tijms <arjan.tijms_at_gmail.com>
>>> wrote:
>>>
>>>> Hi,
>>>>
>>>> It's indeed my suggestion to create another type of Credential.
>>>>
>>>> The reasoning is that authorize only is really a special case of any
>>>> other authenticate + authorize, where the credential secret to check is
>>>> trivial (namely, the empty check).
>>>>
>>>>
>>>> >Because you can end up that a certain IdentityStore receives another
>>>> type of Credentials in the case it is used alone or in combination with
>>>> other stores.
>>>>
>>>> I know, and I can see how this may introduce some confusion. In fact,
>>>> we started the core IdentityStore discussion with exactly this point. This
>>>> is why the current IdentityStore has the super type Credential as input.
>>>> It's already required to handle multiple concrete Credential types. Back
>>>> then no consensus was reached on how to simplify this aspect.
>>>>
>>>> If the special system Credential I proposed was the first additional
>>>> credential a store had to handle, then indeed, it's an extra complexity
>>>> that wasn't there before. But in this case, that complexity, for better or
>>>> worse, is already there.
>>>>
>>>> E.g. suppose IdentityStoreX is able to handle
>>>> UsernamePasswordCredential and TokenCredential today. In the current
>>>> situation, what happens is:
>>>>
>>>> 1. UsernamePasswordCredential is passed in. Store validates password
>>>> matches username and/or uses username and (hashed) password to lookup and
>>>> return principal + groups
>>>> 2. TokenCredential is passed in. Store validates token and uses it to lookup
>>>> and return principal + groups
>>>>
>>>> Now add the CallerPrincipalCredential:
>>>>
>>>> 1. UsernamePasswordCredential is passed in. Store validates password
>>>> matches username and uses username or both to lookup and return principal +
>>>> groups
>>>> 2. TokenCredential is passed in. Store validates token and uses it to lookup
>>>> and return principal + groups
>>>> 3. CallerPrincipalCredential is passed in. Store validates principal
>>>> and uses it to lookup and return principal + groups
>>>>
>>>> So there's no difference in what the store already does.
>>>>
>>>> It doesn't really matter so much if the store is used alone or in
>>>> combination, but it matters that the store is capable of handling a
>>>> credential of type "CallerPrincipal". That credential could be used in case
>>>> of multiple stores for authorize only, but it could also be used for a
>>>> RunAs feature, it could be used to automatically log-in a user after
>>>> registration and to programmatically log-out/log-in the user (e.g. to
>>>> refresh the current name/groups).
>>>>
>>>> So if anything this should only increase reusability, as the capability
>>>> to do authorize only, can be re-used for the cases mentioned above.
>>>>
>>>> What I could see down the line (and was a previous proposal) is that we
>>>> add several Interfaces that a store could optionally implement. Something
>>>> like
>>>>
>>>> public interface GroupStore {
>>>> List<String> getGroupsByCallerPrincipal(CallerPrincipal
>>>> callerPrincipal);
>>>> }
>>>>
>>>> Or using the not yet introduced type Caller (which holds the principal
>>>> + groups):
>>>>
>>>> public class Caller {
>>>> CallerPrincipal callerPrincipal;
>>>> List<String> groups;
>>>> }
>>>>
>>>> public interface GroupStore {
>>>> Caller getCallerByCallerPrincipal(CallerPrincipal callerPrincipal);
>>>> }
>>>>
>>>> >Maybe it is better that you create the code and that I verify how I
>>>> can use them in those situations.
>>>>
>>>> Okay sure, let's do that then. Perhaps easiest is if I first accept the
>>>> PR, then make some small changes, declare it a version m2, and then for m3
>>>> see how we go from there. Would that be okay?
>>>>
>>>> Kind regards,
>>>> Arjan Tijms
>>>>
>>>>
>>>>
>>>>
>>>> On Tue, Sep 6, 2016 at 9:50 PM, Rudy De Busscher <rdebusscher_at_gmail.com
>>>> > wrote:
>>>>
>>>>> Arjan,
>>>>>
>>>>> We are again at the point where you suggest that the system should
>>>>> create another Credential and pass this to the IdentityStore. I don't like
>>>>> that and it is also confusing.
>>>>> Because you can end up that a certain IdentityStore receives another
>>>>> type of Credentials in the case it is used alone or in combination with
>>>>> other stores. Or depending the developer defines it as ValidationType.BOTH
>>>>> or ValidationType.AUTHORIZATION.
>>>>>
>>>>> This limits the reusability of them enormously.
>>>>>
>>>>> I modeled the system according to the needs I had the last five years
>>>>> or so. Maybe it is better that you create the code and that I verify how I
>>>>> can use them in those situations.
>>>>>
>>>>> Best Regards
>>>>> Rudy
>>>>>
>>>>>
>>>>> On 6 September 2016 at 17:18, arjan tijms <arjan.tijms_at_gmail.com>
>>>>> wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On Tue, Sep 6, 2016 at 4:31 PM, Rudy De Busscher <
>>>>>> rdebusscher_at_gmail.com> wrote:
>>>>>>
>>>>>>> Hi Arjan,
>>>>>>>
>>>>>>> Thanks for your feedback.
>>>>>>>
>>>>>>
>>>>>> Thank you too ;)
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> A quick reply to your comments.
>>>>>>>
>>>>>>> I wonder, would it be possible to omit the CallerPrincipal argument
>>>>>>>> here? There's already a caller in the Credential, and I'm afraid this would
>>>>>>>> confuse people who have to implement the interface.
>>>>>>>
>>>>>>>
>>>>>>> I don't like the caller in the Credential interface
>>>>>>> - Credentials are user supplied and should be separated from the
>>>>>>> "System determined values". The caller(Principal) is something which is
>>>>>>> determined based on the credentials and thus I should not mix these 2
>>>>>>> sources.
>>>>>>>
>>>>>>
>>>>>> Perhaps, but if the store is asked for authorization only no actual
>>>>>> user supplied credential is needed, just the caller name to get the groups
>>>>>> by, which can be put in a dedicated system credential.
>>>>>>
>>>>>>
>>>>>>
>>>>>>> - The current implementation of UsernamePasswordCredential uses the
>>>>>>> user-supplied username as value.
>>>>>>>
>>>>>>
>>>>>>
>>>>>> If the UsernamePasswordCredential is used for authentication, then
>>>>>> this can be passed in as-is. If the caller is authenticated via an earlier
>>>>>> call to an earlier identity store, then the handler knows this. If a
>>>>>> followup store is configured for authorization only, the handler knows
>>>>>> this, and can pass in the right system credential. This system credential
>>>>>> can only contain the caller principal.
>>>>>>
>>>>>> So in these two situations only ever 1 caller name/principal is
>>>>>> needed. By passing them in both at the same time, depending on the
>>>>>> situation one or the other is used.
>>>>>>
>>>>>> The problem now is that a store that doesn't want to have anything to
>>>>>> do with multi stores, sees two incoming principals (names). The one in the
>>>>>> credential, and the one passed in as a separate argument. We have to tell
>>>>>> users that unless they want to support authorise only and be multi store
>>>>>> capable, they have to ignore the second parameter. IMHO this goes against
>>>>>> the simplest possible design.
>>>>>>
>>>>>>
>>>>>>
>>>>>>> So there is no way to determine if the 'Caller' is already
>>>>>>> identified or not. And this is a key principal when the Authorization and
>>>>>>> Authentication is separated in different identityStores.
>>>>>>>
>>>>>>
>>>>>> I think determining if the Caller is identified is a responsibility
>>>>>> that should lie solely with the handler. The store just does what it's
>>>>>> asked to do based on the incoming data and whether it's configured to do
>>>>>> authentication, authorization or both. The handler on its turn knows
>>>>>> everything, via the returned status in the CredentialValidationResult and
>>>>>> the returned Principal of each store.
>>>>>>
>>>>>>
>>>>>>
>>>>>>> - The unique caller identification doesn't need to be the same as
>>>>>>> user-supplied username (you can decide to use the internal id/sequence,
>>>>>>> email address, LDAP node cn value, ...)
>>>>>>>
>>>>>>
>>>>>> Indeed, and that's a key design element in the current store. The
>>>>>> credential may contain a caller name (like e.g. in
>>>>>> UsernamePasswordCredential), but the CredentialValidationResult contains
>>>>>> both CallerPrincipal and CallerGroups return values. That CallerPrincipal
>>>>>> is then taken as the one belonging to the authenticated identity.
>>>>>>
>>>>>> As an example: suppose we have the LDAPIdentityStore set to
>>>>>> authenticate against and the DatabaseIdentityStore set to get the groups
>>>>>> from. Now suppose we couple that to a mechanism that uses the
>>>>>> UsernamePasswordCredential.
>>>>>>
>>>>>> Now let the caller authenticate with caller name "pete" and password
>>>>>> "secret", then:
>>>>>>
>>>>>> 1. The handler constructs a UsernamePasswordCredential and passes
>>>>>> that into the LDAPIdentityStore.
>>>>>>
>>>>>> 2. The LDAPIdentityStore validates that and returns a VALID result
>>>>>> with CallerPrincipal(name="cn=pete, dn=peter parker") and no groups.
>>>>>>
>>>>>> 3. The handler then takes CallerPrincipal(name="cn=pete, dn=peter
>>>>>> parker"), puts that into a suitable system Credential and passes that into
>>>>>> the DatabaseIdentityStore.
>>>>>>
>>>>>> 4. The DatabaseIdentityStore then returns the groups associated with
>>>>>> CallerPrincipal(name="cn=pete, dn=peter parker") say {"foo", "bar", "kaz"}
>>>>>>
>>>>>> 5. The handler now combines CallerPrincipal(name="cn=pete, dn=peter
>>>>>> parker") and {"foo", "bar", "kaz"} puts that into the final
>>>>>> CredentialValidationResult and returns it.
>>>>>>
>>>>>> Hope the above demonstrates that it should not be needed to have 2
>>>>>> caller principals passed in, and that the stores can do their work without
>>>>>> having knowledge of what happened before.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> callerPrincipal.getName() would be null here
>>>>>>>
>>>>>>> This should never return null. callerPrincipal being not null means
>>>>>>> a successful Authorization is carried out and thus the user should be
>>>>>>> identifiable (and null is thus not an option)
>>>>>>>
>>>>>>
>>>>>> Indeed, that's what I thought, so therefor if it can never be null
>>>>>> perhaps the store implementations don't have to check against null?
>>>>>>
>>>>>> Kind regards,
>>>>>> Arjan Tijms
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> maybe it's better to have ValidationType directly on the
>>>>>>>> EmbeddedIdentityStoreDefinition (and other definitions)?
>>>>>>>
>>>>>>>
>>>>>>> That is indeed an option.
>>>>>>>
>>>>>>> Best regards
>>>>>>> Rudy
>>>>>>>
>>>>>>> On 4 September 2016 at 21:28, arjan tijms <arjan.tijms_at_gmail.com>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Hi Rudy,
>>>>>>>>
>>>>>>>> Looks much improved, thanks!
>>>>>>>>
>>>>>>>> I have a few comments, but some are just cosmetic and could be
>>>>>>>> looked at later.
>>>>>>>>
>>>>>>>> The most important one concerns the IdentityStore interface, it now
>>>>>>>> has this method:
>>>>>>>>
>>>>>>>> public CredentialValidationResult validate(Credential credential,
>>>>>>>> CallerPrincipal callerPrincipal) {
>>>>>>>>
>>>>>>>> I wonder, would it be possible to omit the CallerPrincipal argument
>>>>>>>> here? There's already a caller in the Credential, and I'm afraid this would
>>>>>>>> confuse people who have to implement the interface. I may also give the
>>>>>>>> impression to implementors that they have to take the history of what
>>>>>>>> happened before with other stores somehow into account. I think it would be
>>>>>>>> best if the store itself is totally unaware of the concept of multiple
>>>>>>>> stores, since that's what the handler should do. Since the handler is
>>>>>>>> replaceable, a store implementation can't assume anything about it.
>>>>>>>>
>>>>>>>> In the implementations of the provided stores (e.g. the
>>>>>>>> EmbeddedIdentityStore), there's this comment with some code below it.
>>>>>>>>
>>>>>>>> // We check also if caller != null to be sure the Authentication by
>>>>>>>> another IdentityStore succeeded.
>>>>>>>>
>>>>>>>> If you look at the code flow that applies to it's:
>>>>>>>>
>>>>>>>> String caller = null;
>>>>>>>> ...
>>>>>>>> // We are Authorize Only mode, so get the caller
>>>>>>>> determined previously.
>>>>>>>> if (callerPrincipal != null) {
>>>>>>>> caller = callerPrincipal.getName();
>>>>>>>> }
>>>>>>>>
>>>>>>>> if (authenticated && caller != null) {
>>>>>>>> ...
>>>>>>>> }
>>>>>>>>
>>>>>>>> return INVALID_RESULT;
>>>>>>>>
>>>>>>>> So it callerPrincipal or callerPrincipal.getName() would be null
>>>>>>>> here, the store would return INVALID_RESULT. But in that case, wouldn't it
>>>>>>>> be better if the handler did not call the store at all? That would safe the
>>>>>>>> store from having to check this case or even having to think of what other
>>>>>>>> stores before it did. In other words, define in the contract and spec that
>>>>>>>> if the store is used for authorization, the passed in caller is not null.
>>>>>>>> Would that make sense?
>>>>>>>>
>>>>>>>> The idea here would be that a store is kept as simple as it can
>>>>>>>> possibly be, as an often heard complaint is that all proprietary stores are
>>>>>>>> quite complex. The multi-store algorithm should then 100% be with the
>>>>>>>> handler.
>>>>>>>>
>>>>>>>> A somewhat cosmetic and implementation thing, but maybe still worth
>>>>>>>> it to look at is this pattern in the stores:
>>>>>>>>
>>>>>>>> private EmbeddedIdentityStoreDefinitio
>>>>>>>> n embeddedIdentityStoreDefinition;
>>>>>>>>
>>>>>>>> private ValidationType validationType;
>>>>>>>>
>>>>>>>> private void determineValidationType() {
>>>>>>>> validationType = ValidationType.BOTH;
>>>>>>>> if (embeddedIdentityStoreDefinition.authenticateOnly()) {
>>>>>>>> validationType = ValidationType.AUTHENTICATION;
>>>>>>>> } else {
>>>>>>>> if (embeddedIdentityStoreDefinition.authorizeOnly()) {
>>>>>>>> validationType = ValidationType.AUTHORIZATION;
>>>>>>>> }
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>> public ValidationType validationType() {
>>>>>>>> return validationType;
>>>>>>>> }
>>>>>>>>
>>>>>>>> Seeing this code repeating, maybe it's better to have
>>>>>>>> ValidationType directly on the EmbeddedIdentityStoreDefinition
>>>>>>>> (and other definitions)?
>>>>>>>>
>>>>>>>> Then it could just be:
>>>>>>>>
>>>>>>>> public ValidationType validationType() {
>>>>>>>> return embeddedIdentityStoreDefinition.validationType();
>>>>>>>> }
>>>>>>>>
>>>>>>>> Another small thing, also cosmetic mostly, but there's now this
>>>>>>>> kind of check often:
>>>>>>>>
>>>>>>>> if (validationType == ValidationType.AUTHENTICATION ||
>>>>>>>> validationType == ValidationType.BOTH) {
>>>>>>>> ...
>>>>>>>> }
>>>>>>>>
>>>>>>>> What about making two helper methods on the ValidationType enum
>>>>>>>> like e.g.
>>>>>>>>
>>>>>>>> public boolean isAuthentication() {
>>>>>>>> return isOneOf(this, AUTHENTICATION, BOTH);
>>>>>>>> }
>>>>>>>>
>>>>>>>> then the code using it could just do:
>>>>>>>>
>>>>>>>> if (validationType.isAuthentication()) {
>>>>>>>> ...
>>>>>>>> }
>>>>>>>>
>>>>>>>> Hope this feedback is useful ;)
>>>>>>>>
>>>>>>>> Kind regards,
>>>>>>>> Arjan Tijms
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Sun, Sep 4, 2016 at 8:07 PM, Rudy De Busscher <
>>>>>>>> rdebusscher_at_gmail.com> wrote:
>>>>>>>>
>>>>>>>>> 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/afa4cecf626266
>>>>>>>>> d0ae400f806b0358ed7b07bc61
>>>>>>>>> And are added to the first pull request to the Soteria repository.
>>>>>>>>>
>>>>>>>>> Best regards
>>>>>>>>> Rudy
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> You received this message because you are subscribed to the Google
>>>>>>>>> Groups "Java EE Security API - JSR 375 - Experts" group.
>>>>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>>>>> send an email to jsr375-experts+unsubscribe_at_googlegroups.com.
>>>>>>>>> To post to this group, send email to
>>>>>>>>> jsr375-experts_at_googlegroups.com.
>>>>>>>>> To view this discussion on the web visit
>>>>>>>>> https://groups.google.com/d/msgid/jsr375-experts/CAL%2Bwt-5Q
>>>>>>>>> mUqZiZ9V2uTYXAE-A%2B%2BFrzNwYKkYxmZBxaHyYLq15g%40mail.gmail.com
>>>>>>>>> <https://groups.google.com/d/msgid/jsr375-experts/CAL%2Bwt-5QmUqZiZ9V2uTYXAE-A%2B%2BFrzNwYKkYxmZBxaHyYLq15g%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>>>>>> .
>>>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>