You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltaspike.apache.org by Shane Bryzak <sb...@redhat.com> on 2012/02/28 23:15:45 UTC

[DISCUSS] DELTASPIKE-76 Authentication API

With the basic implementation of Identity now in place, it's now a good 
time to discuss authentication.  The authentication API comes into play 
during the user authentication process, and is responsible for ensuring 
that the user is who they claim to be, and providing the application 
with the user's assigned role and group privileges.  The authentication 
API is not invoked directly by the user, rather it is consumed by the 
login process when the user invokes Identity.login().  It should be 
easily configured and simple to extend.

The following code shows the proposed SPI interface for Authenticator, 
an implementation of which manages the authentication process:

public interface Authenticator
{
     public enum AuthenticationStatus {SUCCESS, FAILURE, DEFERRED}

     void authenticate();

     void postAuthenticate();

     AuthenticationStatus getStatus();

     User getUser();

     Set<Role> getRoleMemberships();

     Set<Group> getGroupMemberships();
}

The AuthenticationStatus enum / getStatus() method are used to indicate 
the current state of authentication.  Once the authenticate() method has 
been invoked and completed, in most cases the getStatus() method will 
return a result of SUCCESS or FAILURE, indicating whether the 
authentication process was successful or not.  In more complex forms of 
Authentication (such as OpenID) the getStatus() method will return an 
immediate result of DEFERRED, indicating that the authentication process 
is still underway.

The postAuthenticate() method in most cases will do nothing, however is 
provided once again for more complex authentication scenarios.  It 
allows the authenticator to perform finalisation of the authentication 
process, for example in cases where authentication is asynchronous.

The last three methods are responsible for providing the user's state to 
the Identity bean.  The User instance, along with their role and group 
privileges will be used to populate Identity for the duration of the 
user's session.

I propose that we provide the following Authenticator implementations 
out of the box:

1. IdmAuthenticator - Performs user authentication against the Identity 
Management API

2. JaasAuthenticator - Allows the user to use an existing JAAS 
configuration to authenticate with

3. OpenIdAuthenticator - Performs authentication using an OpenID 
provider, such as Google

We can easily extend this list in the future.  I furthermore propose the 
following logic to select which Authenticator will be used when invoking 
Identity.login(), in descending order of priority:

1. If the developer has configured a specific Authenticator 
implementation to use by setting Identity.authenticatorClass, then use 
that Authenticator.

2. If the user has selected a specific authenticator to use by name, by 
setting Identity.authenticatorName, then lookup the Authenticator with 
that name and use it.  This use case is useful for when you wish to 
provide multiple authentication alternatives to the user.  For example, 
Sourceforge allows a user to either log in using their Sourceforge 
username and password, or with their OpenID account.

3. If the developer has provided their own Authenticator implementation, 
then use it to authenticate.  This is the simplest use case and allows 
the developer to control the authentication process themselves.

4. If the Identity Management API has been configured and identity 
management services are available, then use IdmAuthenticator to 
authenticate the user against the configured identity store.

This authenticator selection process provides sensible defaults, while 
allowing the developer to easily control and/or override the 
authenticator configuration.





Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Jason Porter <li...@gmail.com>.
Sounds like a good approach. The selected authenticator will be done via some sort of config or via a setter or similar?

Sent from my iPhone

On Feb 29, 2012, at 15:36, Gerhard Petracek <ge...@gmail.com> wrote:

> @others:
> 
> fyi - it looks like there was just a misunderstanding and after a short
> discussion we agreed on:
> - authenticators are cdi beans
> - just one authenticator is active for the authorization process
> - we need something like AuthenticatorSelector#getSelectedAuthenticator to
> provide the current authenticator
> 
> regards,
> gerhard
> 
> 
> 
> 2012/2/29 Shane Bryzak <sb...@redhat.com>
> 
>> On 29/02/12 21:42, Gerhard Petracek wrote:
>> 
>>> hi shane,
>>> 
>>> imo implementations of Authenticator should be normal cdi beans annotated
>>> with @Alternative, if they shouldn't be enabled by default (and we can use
>>> (global) cdi alternatives to allow custom implementations).
>>> ->  we wouldn't need Identity.authenticatorClass and
>>> Identity.authenticatorName.
>>> 
>> 
>> I don't see any advantage in making the Authenticators alternatives, on
>> the contrary it creates an additional configuration burden for the
>> developer who must then enable the ones they want to use.  It also wouldn't
>> alleviate the requirement for Identity.authenticatorClass and
>> Identity.authenticatorName as there are use-cases for these, one of which
>> I've already mentioned in the sourceforge.net example.
>> 
>> Another example of a use case where Identity.authenticatorClass is
>> important was described by a Seam user some time ago - Say your application
>> has both a public and private facing user interface; for the default,
>> public interface authentication should be performed one way using one
>> particular Authenticator implementation, while for the private interface
>> the authentication process may be required to use a different database
>> table (or some other identity storage) to authenticate against, requiring a
>> different Authenticator to be used.  By being able to set the specific
>> Authenticator class the login process can control which Authenticator is
>> used.  Here's some code to demonstrate:
>> 
>> public @Model class SecurityActions
>> {
>>   @Inject Identity identity;
>> 
>>   public void publicLogin()
>>   {
>>       identity.**setAuthenticatorClass(**DefaultAuthenticator.class);
>>       identity.login();
>>   }
>> 
>>   public void internalLogin()
>>   {
>>       identity.**setAuthenticatorClass(**InternalAuthenticator.class);
>>       identity.login();
>> 
>>   }
>> }
>> 
>> 
>>> @ AuthenticationStatus.DEFERRED and #postAuthenticate:
>>> it would be great, if you can provide a source-code example which shows
>>> the
>>> usage.
>>> 
>> 
>> Here's an example of a deferred authentication from Seam's
>> OpenIdAuthenticator:
>> 
>>   public void authenticate()
>>   {
>>       OpenIdProvider selectedProvider = getSelectedProvider();
>>       if (selectedProvider == null)
>>       {
>>           throw new IllegalStateException("No OpenID provider has been
>> selected");
>>       }
>> 
>>       OpenIdRelyingPartyApi openIdApi = openIdApiInstance.get();
>> 
>>       List<OpenIdRequestedAttribute> attributes = new LinkedList<**
>> OpenIdRequestedAttribute>();
>> 
>>       selectedProvider.**requestAttributes(openIdApi, attributes);
>> 
>>       openIdApi.login(**selectedProvider.getUrl(), attributes,
>> getResponse());
>> 
>>       setStatus(**AuthenticationStatus.DEFERRED)**;
>>   }
>> 
>> In this case, control of the user's browser is handed off to an OpenID
>> provider.  Once the user authenticates successfully, they are then
>> redirected back to a landing page in your own application which then
>> completes the authentication process.
>> 
>> I don't have a specific example for postAuthenticate(), however it could
>> be used for any number of things ranging from auditing, to
>> post-authentication population of roles and groups in environments where
>> loading these resources may be an expensive operation that you may not wish
>> to perform until authentication is successful.
>> 
>> 
>> 
>> 
>>> @get*Memberships
>>> currently i'm thinking about the dis-/advantages of moving those methods
>>> to
>>> User (or something like AuthenticatedUser)
>>> 
>> 
>> I think this would create complications when we start getting into the
>> Identity Management API.  The User object is intended to be a
>> self-contained, atomic representation of a single user and isn't intended
>> to contain state regarding the user's relationships or membership
>> privileges.  It's used in many Identity Management related operations and
>> the addition of this extra state would likely be problematic - I'm sure
>> Bolek could add more to this.
>> 
>>> 
>>> regards,
>>> gerhard
>>> 
>>> 
>>> 
>>> 2012/2/28 Shane Bryzak<sb...@redhat.com>
>>> 
>>> Following on, here's an extremely basic example of an Authenticator.  If
>>>> a
>>>> developer were to simply include this class in their application and
>>>> perform no further configuration, then it would be used during the
>>>> authentication process:
>>>> 
>>>> public class SimpleAuthenticator extends BaseAuthenticator implements
>>>> Authenticator
>>>> {
>>>>   @Inject
>>>>   Credentials credentials;
>>>> 
>>>>   public void authenticate()
>>>>  {
>>>>       if ("demo".equals(credentials.****getUsername())&&
>>>>               credentials.getCredential() instanceof
>>>> PasswordCredential&&
>>>>               "demo".equals(((****PasswordCredential)
>>>> credentials.getCredential()).****getValue())) {
>>>>           setStatus(****AuthenticationStatus.SUCCESS);
>>>> 
>>>>           setUser(new SimpleUser("demo"));
>>>>       }
>>>>       else
>>>>       {
>>>>           setStatus(****AuthenticationStatus.FAILURE);
>>>> 
>>>>       }
>>>>   }
>>>> }
>>>> 
>>>> In this example, BaseAuthenticator is an abstract class that implements
>>>> most of the Authenticator methods and simply allows the subclass to
>>>> invoke
>>>> setStatus / setUser / addGroup etc to set the user's authentication
>>>> state.
>>>> 
>>>> 
>>>> On 29/02/12 08:15, Shane Bryzak wrote:
>>>> 
>>>> With the basic implementation of Identity now in place, it's now a good
>>>>> time to discuss authentication.  The authentication API comes into play
>>>>> during the user authentication process, and is responsible for ensuring
>>>>> that the user is who they claim to be, and providing the application
>>>>> with
>>>>> the user's assigned role and group privileges.  The authentication API
>>>>> is
>>>>> not invoked directly by the user, rather it is consumed by the login
>>>>> process when the user invokes Identity.login().  It should be easily
>>>>> configured and simple to extend.
>>>>> 
>>>>> The following code shows the proposed SPI interface for Authenticator,
>>>>> an
>>>>> implementation of which manages the authentication process:
>>>>> 
>>>>> public interface Authenticator
>>>>> {
>>>>>   public enum AuthenticationStatus {SUCCESS, FAILURE, DEFERRED}
>>>>> 
>>>>>   void authenticate();
>>>>> 
>>>>>   void postAuthenticate();
>>>>> 
>>>>>   AuthenticationStatus getStatus();
>>>>> 
>>>>>   User getUser();
>>>>> 
>>>>>   Set<Role>  getRoleMemberships();
>>>>> 
>>>>>   Set<Group>  getGroupMemberships();
>>>>> }
>>>>> 
>>>>> The AuthenticationStatus enum / getStatus() method are used to indicate
>>>>> the current state of authentication.  Once the authenticate() method has
>>>>> been invoked and completed, in most cases the getStatus() method will
>>>>> return a result of SUCCESS or FAILURE, indicating whether the
>>>>> authentication process was successful or not.  In more complex forms of
>>>>> Authentication (such as OpenID) the getStatus() method will return an
>>>>> immediate result of DEFERRED, indicating that the authentication
>>>>> process is
>>>>> still underway.
>>>>> 
>>>>> The postAuthenticate() method in most cases will do nothing, however is
>>>>> provided once again for more complex authentication scenarios.  It
>>>>> allows
>>>>> the authenticator to perform finalisation of the authentication process,
>>>>> for example in cases where authentication is asynchronous.
>>>>> 
>>>>> The last three methods are responsible for providing the user's state to
>>>>> the Identity bean.  The User instance, along with their role and group
>>>>> privileges will be used to populate Identity for the duration of the
>>>>> user's
>>>>> session.
>>>>> 
>>>>> I propose that we provide the following Authenticator implementations
>>>>> out
>>>>> of the box:
>>>>> 
>>>>> 1. IdmAuthenticator - Performs user authentication against the Identity
>>>>> Management API
>>>>> 
>>>>> 2. JaasAuthenticator - Allows the user to use an existing JAAS
>>>>> configuration to authenticate with
>>>>> 
>>>>> 3. OpenIdAuthenticator - Performs authentication using an OpenID
>>>>> provider, such as Google
>>>>> 
>>>>> We can easily extend this list in the future.  I furthermore propose the
>>>>> following logic to select which Authenticator will be used when invoking
>>>>> Identity.login(), in descending order of priority:
>>>>> 
>>>>> 1. If the developer has configured a specific Authenticator
>>>>> implementation to use by setting Identity.authenticatorClass, then use
>>>>> that
>>>>> Authenticator.
>>>>> 
>>>>> 2. If the user has selected a specific authenticator to use by name, by
>>>>> setting Identity.authenticatorName, then lookup the Authenticator with
>>>>> that
>>>>> name and use it.  This use case is useful for when you wish to provide
>>>>> multiple authentication alternatives to the user.  For example,
>>>>> Sourceforge
>>>>> allows a user to either log in using their Sourceforge username and
>>>>> password, or with their OpenID account.
>>>>> 
>>>>> 3. If the developer has provided their own Authenticator implementation,
>>>>> then use it to authenticate.  This is the simplest use case and allows
>>>>> the
>>>>> developer to control the authentication process themselves.
>>>>> 
>>>>> 4. If the Identity Management API has been configured and identity
>>>>> management services are available, then use IdmAuthenticator to
>>>>> authenticate the user against the configured identity store.
>>>>> 
>>>>> This authenticator selection process provides sensible defaults, while
>>>>> allowing the developer to easily control and/or override the
>>>>> authenticator
>>>>> configuration.
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>> 

Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Gerhard Petracek <ge...@gmail.com>.
@others:

fyi - it looks like there was just a misunderstanding and after a short
discussion we agreed on:
 - authenticators are cdi beans
 - just one authenticator is active for the authorization process
 - we need something like AuthenticatorSelector#getSelectedAuthenticator to
provide the current authenticator

regards,
gerhard



2012/2/29 Shane Bryzak <sb...@redhat.com>

> On 29/02/12 21:42, Gerhard Petracek wrote:
>
>> hi shane,
>>
>> imo implementations of Authenticator should be normal cdi beans annotated
>> with @Alternative, if they shouldn't be enabled by default (and we can use
>> (global) cdi alternatives to allow custom implementations).
>> ->  we wouldn't need Identity.authenticatorClass and
>> Identity.authenticatorName.
>>
>
> I don't see any advantage in making the Authenticators alternatives, on
> the contrary it creates an additional configuration burden for the
> developer who must then enable the ones they want to use.  It also wouldn't
> alleviate the requirement for Identity.authenticatorClass and
> Identity.authenticatorName as there are use-cases for these, one of which
> I've already mentioned in the sourceforge.net example.
>
> Another example of a use case where Identity.authenticatorClass is
> important was described by a Seam user some time ago - Say your application
> has both a public and private facing user interface; for the default,
> public interface authentication should be performed one way using one
> particular Authenticator implementation, while for the private interface
> the authentication process may be required to use a different database
> table (or some other identity storage) to authenticate against, requiring a
> different Authenticator to be used.  By being able to set the specific
> Authenticator class the login process can control which Authenticator is
> used.  Here's some code to demonstrate:
>
> public @Model class SecurityActions
> {
>    @Inject Identity identity;
>
>    public void publicLogin()
>    {
>        identity.**setAuthenticatorClass(**DefaultAuthenticator.class);
>        identity.login();
>    }
>
>    public void internalLogin()
>    {
>        identity.**setAuthenticatorClass(**InternalAuthenticator.class);
>        identity.login();
>
>    }
> }
>
>
>> @ AuthenticationStatus.DEFERRED and #postAuthenticate:
>> it would be great, if you can provide a source-code example which shows
>> the
>> usage.
>>
>
> Here's an example of a deferred authentication from Seam's
> OpenIdAuthenticator:
>
>    public void authenticate()
>    {
>        OpenIdProvider selectedProvider = getSelectedProvider();
>        if (selectedProvider == null)
>        {
>            throw new IllegalStateException("No OpenID provider has been
> selected");
>        }
>
>        OpenIdRelyingPartyApi openIdApi = openIdApiInstance.get();
>
>        List<OpenIdRequestedAttribute> attributes = new LinkedList<**
> OpenIdRequestedAttribute>();
>
>        selectedProvider.**requestAttributes(openIdApi, attributes);
>
>        openIdApi.login(**selectedProvider.getUrl(), attributes,
> getResponse());
>
>        setStatus(**AuthenticationStatus.DEFERRED)**;
>    }
>
> In this case, control of the user's browser is handed off to an OpenID
> provider.  Once the user authenticates successfully, they are then
> redirected back to a landing page in your own application which then
> completes the authentication process.
>
> I don't have a specific example for postAuthenticate(), however it could
> be used for any number of things ranging from auditing, to
> post-authentication population of roles and groups in environments where
> loading these resources may be an expensive operation that you may not wish
> to perform until authentication is successful.
>
>
>
>
>> @get*Memberships
>> currently i'm thinking about the dis-/advantages of moving those methods
>> to
>> User (or something like AuthenticatedUser)
>>
>
> I think this would create complications when we start getting into the
> Identity Management API.  The User object is intended to be a
> self-contained, atomic representation of a single user and isn't intended
> to contain state regarding the user's relationships or membership
> privileges.  It's used in many Identity Management related operations and
> the addition of this extra state would likely be problematic - I'm sure
> Bolek could add more to this.
>
>>
>> regards,
>> gerhard
>>
>>
>>
>> 2012/2/28 Shane Bryzak<sb...@redhat.com>
>>
>>  Following on, here's an extremely basic example of an Authenticator.  If
>>> a
>>> developer were to simply include this class in their application and
>>> perform no further configuration, then it would be used during the
>>> authentication process:
>>>
>>> public class SimpleAuthenticator extends BaseAuthenticator implements
>>> Authenticator
>>> {
>>>    @Inject
>>>    Credentials credentials;
>>>
>>>    public void authenticate()
>>>   {
>>>        if ("demo".equals(credentials.****getUsername())&&
>>>                credentials.getCredential() instanceof
>>> PasswordCredential&&
>>>                "demo".equals(((****PasswordCredential)
>>> credentials.getCredential()).****getValue())) {
>>>            setStatus(****AuthenticationStatus.SUCCESS);
>>>
>>>            setUser(new SimpleUser("demo"));
>>>        }
>>>        else
>>>        {
>>>            setStatus(****AuthenticationStatus.FAILURE);
>>>
>>>        }
>>>    }
>>> }
>>>
>>> In this example, BaseAuthenticator is an abstract class that implements
>>> most of the Authenticator methods and simply allows the subclass to
>>> invoke
>>> setStatus / setUser / addGroup etc to set the user's authentication
>>> state.
>>>
>>>
>>> On 29/02/12 08:15, Shane Bryzak wrote:
>>>
>>>  With the basic implementation of Identity now in place, it's now a good
>>>> time to discuss authentication.  The authentication API comes into play
>>>> during the user authentication process, and is responsible for ensuring
>>>> that the user is who they claim to be, and providing the application
>>>> with
>>>> the user's assigned role and group privileges.  The authentication API
>>>> is
>>>> not invoked directly by the user, rather it is consumed by the login
>>>> process when the user invokes Identity.login().  It should be easily
>>>> configured and simple to extend.
>>>>
>>>> The following code shows the proposed SPI interface for Authenticator,
>>>> an
>>>> implementation of which manages the authentication process:
>>>>
>>>> public interface Authenticator
>>>> {
>>>>    public enum AuthenticationStatus {SUCCESS, FAILURE, DEFERRED}
>>>>
>>>>    void authenticate();
>>>>
>>>>    void postAuthenticate();
>>>>
>>>>    AuthenticationStatus getStatus();
>>>>
>>>>    User getUser();
>>>>
>>>>    Set<Role>  getRoleMemberships();
>>>>
>>>>    Set<Group>  getGroupMemberships();
>>>> }
>>>>
>>>> The AuthenticationStatus enum / getStatus() method are used to indicate
>>>> the current state of authentication.  Once the authenticate() method has
>>>> been invoked and completed, in most cases the getStatus() method will
>>>> return a result of SUCCESS or FAILURE, indicating whether the
>>>> authentication process was successful or not.  In more complex forms of
>>>> Authentication (such as OpenID) the getStatus() method will return an
>>>> immediate result of DEFERRED, indicating that the authentication
>>>> process is
>>>> still underway.
>>>>
>>>> The postAuthenticate() method in most cases will do nothing, however is
>>>> provided once again for more complex authentication scenarios.  It
>>>> allows
>>>> the authenticator to perform finalisation of the authentication process,
>>>> for example in cases where authentication is asynchronous.
>>>>
>>>> The last three methods are responsible for providing the user's state to
>>>> the Identity bean.  The User instance, along with their role and group
>>>> privileges will be used to populate Identity for the duration of the
>>>> user's
>>>> session.
>>>>
>>>> I propose that we provide the following Authenticator implementations
>>>> out
>>>> of the box:
>>>>
>>>> 1. IdmAuthenticator - Performs user authentication against the Identity
>>>> Management API
>>>>
>>>> 2. JaasAuthenticator - Allows the user to use an existing JAAS
>>>> configuration to authenticate with
>>>>
>>>> 3. OpenIdAuthenticator - Performs authentication using an OpenID
>>>> provider, such as Google
>>>>
>>>> We can easily extend this list in the future.  I furthermore propose the
>>>> following logic to select which Authenticator will be used when invoking
>>>> Identity.login(), in descending order of priority:
>>>>
>>>> 1. If the developer has configured a specific Authenticator
>>>> implementation to use by setting Identity.authenticatorClass, then use
>>>> that
>>>> Authenticator.
>>>>
>>>> 2. If the user has selected a specific authenticator to use by name, by
>>>> setting Identity.authenticatorName, then lookup the Authenticator with
>>>> that
>>>> name and use it.  This use case is useful for when you wish to provide
>>>> multiple authentication alternatives to the user.  For example,
>>>> Sourceforge
>>>> allows a user to either log in using their Sourceforge username and
>>>> password, or with their OpenID account.
>>>>
>>>> 3. If the developer has provided their own Authenticator implementation,
>>>> then use it to authenticate.  This is the simplest use case and allows
>>>> the
>>>> developer to control the authentication process themselves.
>>>>
>>>> 4. If the Identity Management API has been configured and identity
>>>> management services are available, then use IdmAuthenticator to
>>>> authenticate the user against the configured identity store.
>>>>
>>>> This authenticator selection process provides sensible defaults, while
>>>> allowing the developer to easily control and/or override the
>>>> authenticator
>>>> configuration.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>

Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Gerhard Petracek <ge...@gmail.com>.
hi shane,

imo it's better than the first draft -> +1 for committing it.

regards,
gerhard



2012/3/5 Shane Bryzak <sb...@redhat.com>

> Ok I've been thinking about this over the last few days (and come up with
> a number of solutions I wasn't happy with), however there is one idea in
> particular I quite like.  To take a step back for a moment though, the
> reason we were contemplating adding the extra state to the User class was
> so that we could convey that state between the authentication process and
> the user's Identity.  This state (which represents the user's group and
> role privileges) is then used for the duration of the user's session
> whenever the Identity.hasRole() or Identity.hasGroup() methods are invoked,
> to control the user's access to the restricted operations of the
> application and so forth.
>
> Until now I believed that the challenge we had was how we integrate the
> mechanism for this state transfer with the Identity Management API, however
> I have now come to the conclusion that it should be integrated with the
> Identity Management API itself, with the IdentityManager bean managing all
> privilege assignment, both persistent and temporary.  With that in mind,
> I'd like to propose we add the following methods to the IdentityManager
> interface:
>
> grantRoleForSession(User user, Role role);
> grantGroupForSession(User user, Group group);
>
> We can see these methods in action by building on top of the
> SimpleAuthenticator example we saw earlier to now include role and group
> assignment:
>
>
> public class SimpleAuthenticator extends BaseAuthenticator implements
> Authenticator
> {
>    @Inject
>    Credentials credentials;
>
>    @Inject
>    IdentityManager idm;
>
>    public void authenticate()
>   {
>
>        if ("demo".equals(credentials.**getUsername()) &&
>                credentials.getCredential() instanceof PasswordCredential &&
>                "demo".equals(((**PasswordCredential)
> credentials.getCredential()).**getValue()))
>        {
>            setUser(new SimpleUser("demo"));
>            idm.grantRoleForSession(**getUser(), new SimpleRole("ADMIN",
> "USERS"));
>            idm.grantGroupForSession(**getUser(), new
> SimpleGroup("USERS"));
>            setStatus(**AuthenticationStatus.SUCCESS);
>        }
>        else
>        {
>            setStatus(**AuthenticationStatus.FAILURE);
>        }
>    }
> }
>
> This solution is clean, keeps the User class free of additional state and
> consolidates all user privilege management in one place.  It also opens up
> a number of exciting possibilities, one such example being session
> management (manipulation of user privileges at runtime) and makes much
> easier to implement features such as more complex role assignment such as
> temporal based (i.e. grant role X to user Y between the hours of 8am and
> 5pm server time) or expiring (grant role X to user Y for exactly 30 days).
>  It also means auditing can be performed all in one class.
>
>
>
>
> On 02/03/12 06:41, Boleslaw Dawidowicz wrote:
>
>> On Feb 29, 2012, at 10:25 PM, Shane Bryzak wrote:
>>
>>  currently i'm thinking about the dis-/advantages of moving those methods
>>>> to
>>>> User (or something like AuthenticatedUser)
>>>>
>>> I think this would create complications when we start getting into the
>>> Identity Management API.  The User object is intended to be a
>>> self-contained, atomic representation of a single user and isn't intended
>>> to contain state regarding the user's relationships or membership
>>> privileges.  It's used in many Identity Management related operations and
>>> the addition of this extra state would likely be problematic - I'm sure
>>> Bolek could add more to this.
>>>
>> I support Shane on this. It could lead to a lot of complications and not
>> sure what would be benefits of having this.
>>
>> Bolek
>>
>>
>

Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Shane Bryzak <sb...@redhat.com>.
The getRoleMemberships() / getGroupMemberships() methods have now been 
removed, and if the Authenticator wishes to still grant these privileges 
for the user's session it can simply inject the IdentityManager and set 
them there, leaving the Authenticator with just a few concise methods 
related to the authentication process only.  The getUser() method is 
still required as Identity needs to know who the actual user is, but the 
User object contains no state pertaining to the user's privileges.


On 07/03/12 23:31, Paul Dijou wrote:
> Hi,
>
> I still think the Authenticator should only authenticate and doesn't have
> to know anything about how the application handle the notion of User, Group
> and Role. Authenticator should take Credentials in entry, knows where to
> check (database, ldap, ...) and return the result (success, fail, on going,
> ...). That's all. So the Authenticator interface shouldn't have a
> set/getUser() in my opinion. This method could be on the IdentityManager.
>
> I'm saying that because I think about a generic authenticator used by
> several applications connected to a central LDAP for example but each one
> having it's own system around User/Group/Role.
>
> In practice, if an implementation of the Authenticator wants to modify
> directly the User, I'm fine with that, but the API should be as minimalist
> as possible.
>
> Regards,
>
> Paul.
>
> 2012/3/6 Boleslaw Dawidowicz<bo...@gmail.com>
>
>> I like this idea. However my concern is that it will need clear
>> distinction in the IDM API between all roles (including session ones) and
>> persisted roles (identity store level).
>>
>> Bolek
>>
>> On Mar 5, 2012, at 11:45 PM, Shane Bryzak wrote:
>>
>>> Ok I've been thinking about this over the last few days (and come up
>> with a number of solutions I wasn't happy with), however there is one idea
>> in particular I quite like.  To take a step back for a moment though, the
>> reason we were contemplating adding the extra state to the User class was
>> so that we could convey that state between the authentication process and
>> the user's Identity.  This state (which represents the user's group and
>> role privileges) is then used for the duration of the user's session
>> whenever the Identity.hasRole() or Identity.hasGroup() methods are invoked,
>> to control the user's access to the restricted operations of the
>> application and so forth.
>>> Until now I believed that the challenge we had was how we integrate the
>> mechanism for this state transfer with the Identity Management API, however
>> I have now come to the conclusion that it should be integrated with the
>> Identity Management API itself, with the IdentityManager bean managing all
>> privilege assignment, both persistent and temporary.  With that in mind,
>> I'd like to propose we add the following methods to the IdentityManager
>> interface:
>>> grantRoleForSession(User user, Role role);
>>> grantGroupForSession(User user, Group group);
>>>
>>> We can see these methods in action by building on top of the
>> SimpleAuthenticator example we saw earlier to now include role and group
>> assignment:
>>> public class SimpleAuthenticator extends BaseAuthenticator implements
>> Authenticator
>>> {
>>>     @Inject
>>>     Credentials credentials;
>>>
>>>     @Inject
>>>     IdentityManager idm;
>>>
>>>     public void authenticate()
>>>    {
>>>         if ("demo".equals(credentials.getUsername())&&
>>>                 credentials.getCredential() instanceof PasswordCredential
>> &&
>>>                 "demo".equals(((PasswordCredential)
>> credentials.getCredential()).getValue()))
>>>         {
>>>             setUser(new SimpleUser("demo"));
>>>             idm.grantRoleForSession(getUser(), new SimpleRole("ADMIN",
>> "USERS"));
>>>             idm.grantGroupForSession(getUser(), new SimpleGroup("USERS"));
>>>             setStatus(AuthenticationStatus.SUCCESS);
>>>         }
>>>         else
>>>         {
>>>             setStatus(AuthenticationStatus.FAILURE);
>>>         }
>>>     }
>>> }
>>>
>>> This solution is clean, keeps the User class free of additional state
>> and consolidates all user privilege management in one place.  It also opens
>> up a number of exciting possibilities, one such example being session
>> management (manipulation of user privileges at runtime) and makes much
>> easier to implement features such as more complex role assignment such as
>> temporal based (i.e. grant role X to user Y between the hours of 8am and
>> 5pm server time) or expiring (grant role X to user Y for exactly 30 days).
>>   It also means auditing can be performed all in one class.
>>>
>>>
>>> On 02/03/12 06:41, Boleslaw Dawidowicz wrote:
>>>> On Feb 29, 2012, at 10:25 PM, Shane Bryzak wrote:
>>>>
>>>>>> currently i'm thinking about the dis-/advantages of moving those
>> methods to
>>>>>> User (or something like AuthenticatedUser)
>>>>> I think this would create complications when we start getting into the
>> Identity Management API.  The User object is intended to be a
>> self-contained, atomic representation of a single user and isn't intended
>> to contain state regarding the user's relationships or membership
>> privileges.  It's used in many Identity Management related operations and
>> the addition of this extra state would likely be problematic - I'm sure
>> Bolek could add more to this.
>>>> I support Shane on this. It could lead to a lot of complications and
>> not sure what would be benefits of having this.
>>>> Bolek
>>>>
>>


Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Gerhard Petracek <ge...@gmail.com>.
hi paul,

we already had a short (irc) discussion about it and imo we have the same
(or at least a similar) opinion about it.

regards,
gerhard



2012/3/7 Paul Dijou <pa...@gmail.com>

> Hi,
>
> I still think the Authenticator should only authenticate and doesn't have
> to know anything about how the application handle the notion of User, Group
> and Role. Authenticator should take Credentials in entry, knows where to
> check (database, ldap, ...) and return the result (success, fail, on going,
> ...). That's all. So the Authenticator interface shouldn't have a
> set/getUser() in my opinion. This method could be on the IdentityManager.
>
> I'm saying that because I think about a generic authenticator used by
> several applications connected to a central LDAP for example but each one
> having it's own system around User/Group/Role.
>
> In practice, if an implementation of the Authenticator wants to modify
> directly the User, I'm fine with that, but the API should be as minimalist
> as possible.
>
> Regards,
>
> Paul.
>
> 2012/3/6 Boleslaw Dawidowicz <bo...@gmail.com>
>
> > I like this idea. However my concern is that it will need clear
> > distinction in the IDM API between all roles (including session ones) and
> > persisted roles (identity store level).
> >
> > Bolek
> >
> > On Mar 5, 2012, at 11:45 PM, Shane Bryzak wrote:
> >
> > > Ok I've been thinking about this over the last few days (and come up
> > with a number of solutions I wasn't happy with), however there is one
> idea
> > in particular I quite like.  To take a step back for a moment though, the
> > reason we were contemplating adding the extra state to the User class was
> > so that we could convey that state between the authentication process and
> > the user's Identity.  This state (which represents the user's group and
> > role privileges) is then used for the duration of the user's session
> > whenever the Identity.hasRole() or Identity.hasGroup() methods are
> invoked,
> > to control the user's access to the restricted operations of the
> > application and so forth.
> > >
> > > Until now I believed that the challenge we had was how we integrate the
> > mechanism for this state transfer with the Identity Management API,
> however
> > I have now come to the conclusion that it should be integrated with the
> > Identity Management API itself, with the IdentityManager bean managing
> all
> > privilege assignment, both persistent and temporary.  With that in mind,
> > I'd like to propose we add the following methods to the IdentityManager
> > interface:
> > >
> > > grantRoleForSession(User user, Role role);
> > > grantGroupForSession(User user, Group group);
> > >
> > > We can see these methods in action by building on top of the
> > SimpleAuthenticator example we saw earlier to now include role and group
> > assignment:
> > >
> > > public class SimpleAuthenticator extends BaseAuthenticator implements
> > Authenticator
> > > {
> > >    @Inject
> > >    Credentials credentials;
> > >
> > >    @Inject
> > >    IdentityManager idm;
> > >
> > >    public void authenticate()
> > >   {
> > >        if ("demo".equals(credentials.getUsername()) &&
> > >                credentials.getCredential() instanceof
> PasswordCredential
> > &&
> > >                "demo".equals(((PasswordCredential)
> > credentials.getCredential()).getValue()))
> > >        {
> > >            setUser(new SimpleUser("demo"));
> > >            idm.grantRoleForSession(getUser(), new SimpleRole("ADMIN",
> > "USERS"));
> > >            idm.grantGroupForSession(getUser(), new
> SimpleGroup("USERS"));
> > >            setStatus(AuthenticationStatus.SUCCESS);
> > >        }
> > >        else
> > >        {
> > >            setStatus(AuthenticationStatus.FAILURE);
> > >        }
> > >    }
> > > }
> > >
> > > This solution is clean, keeps the User class free of additional state
> > and consolidates all user privilege management in one place.  It also
> opens
> > up a number of exciting possibilities, one such example being session
> > management (manipulation of user privileges at runtime) and makes much
> > easier to implement features such as more complex role assignment such as
> > temporal based (i.e. grant role X to user Y between the hours of 8am and
> > 5pm server time) or expiring (grant role X to user Y for exactly 30
> days).
> >  It also means auditing can be performed all in one class.
> > >
> > >
> > >
> > > On 02/03/12 06:41, Boleslaw Dawidowicz wrote:
> > >> On Feb 29, 2012, at 10:25 PM, Shane Bryzak wrote:
> > >>
> > >>>> currently i'm thinking about the dis-/advantages of moving those
> > methods to
> > >>>> User (or something like AuthenticatedUser)
> > >>> I think this would create complications when we start getting into
> the
> > Identity Management API.  The User object is intended to be a
> > self-contained, atomic representation of a single user and isn't intended
> > to contain state regarding the user's relationships or membership
> > privileges.  It's used in many Identity Management related operations and
> > the addition of this extra state would likely be problematic - I'm sure
> > Bolek could add more to this.
> > >> I support Shane on this. It could lead to a lot of complications and
> > not sure what would be benefits of having this.
> > >>
> > >> Bolek
> > >>
> > >
> >
> >
>

Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Paul Dijou <pa...@gmail.com>.
Hi,

I still think the Authenticator should only authenticate and doesn't have
to know anything about how the application handle the notion of User, Group
and Role. Authenticator should take Credentials in entry, knows where to
check (database, ldap, ...) and return the result (success, fail, on going,
...). That's all. So the Authenticator interface shouldn't have a
set/getUser() in my opinion. This method could be on the IdentityManager.

I'm saying that because I think about a generic authenticator used by
several applications connected to a central LDAP for example but each one
having it's own system around User/Group/Role.

In practice, if an implementation of the Authenticator wants to modify
directly the User, I'm fine with that, but the API should be as minimalist
as possible.

Regards,

Paul.

2012/3/6 Boleslaw Dawidowicz <bo...@gmail.com>

> I like this idea. However my concern is that it will need clear
> distinction in the IDM API between all roles (including session ones) and
> persisted roles (identity store level).
>
> Bolek
>
> On Mar 5, 2012, at 11:45 PM, Shane Bryzak wrote:
>
> > Ok I've been thinking about this over the last few days (and come up
> with a number of solutions I wasn't happy with), however there is one idea
> in particular I quite like.  To take a step back for a moment though, the
> reason we were contemplating adding the extra state to the User class was
> so that we could convey that state between the authentication process and
> the user's Identity.  This state (which represents the user's group and
> role privileges) is then used for the duration of the user's session
> whenever the Identity.hasRole() or Identity.hasGroup() methods are invoked,
> to control the user's access to the restricted operations of the
> application and so forth.
> >
> > Until now I believed that the challenge we had was how we integrate the
> mechanism for this state transfer with the Identity Management API, however
> I have now come to the conclusion that it should be integrated with the
> Identity Management API itself, with the IdentityManager bean managing all
> privilege assignment, both persistent and temporary.  With that in mind,
> I'd like to propose we add the following methods to the IdentityManager
> interface:
> >
> > grantRoleForSession(User user, Role role);
> > grantGroupForSession(User user, Group group);
> >
> > We can see these methods in action by building on top of the
> SimpleAuthenticator example we saw earlier to now include role and group
> assignment:
> >
> > public class SimpleAuthenticator extends BaseAuthenticator implements
> Authenticator
> > {
> >    @Inject
> >    Credentials credentials;
> >
> >    @Inject
> >    IdentityManager idm;
> >
> >    public void authenticate()
> >   {
> >        if ("demo".equals(credentials.getUsername()) &&
> >                credentials.getCredential() instanceof PasswordCredential
> &&
> >                "demo".equals(((PasswordCredential)
> credentials.getCredential()).getValue()))
> >        {
> >            setUser(new SimpleUser("demo"));
> >            idm.grantRoleForSession(getUser(), new SimpleRole("ADMIN",
> "USERS"));
> >            idm.grantGroupForSession(getUser(), new SimpleGroup("USERS"));
> >            setStatus(AuthenticationStatus.SUCCESS);
> >        }
> >        else
> >        {
> >            setStatus(AuthenticationStatus.FAILURE);
> >        }
> >    }
> > }
> >
> > This solution is clean, keeps the User class free of additional state
> and consolidates all user privilege management in one place.  It also opens
> up a number of exciting possibilities, one such example being session
> management (manipulation of user privileges at runtime) and makes much
> easier to implement features such as more complex role assignment such as
> temporal based (i.e. grant role X to user Y between the hours of 8am and
> 5pm server time) or expiring (grant role X to user Y for exactly 30 days).
>  It also means auditing can be performed all in one class.
> >
> >
> >
> > On 02/03/12 06:41, Boleslaw Dawidowicz wrote:
> >> On Feb 29, 2012, at 10:25 PM, Shane Bryzak wrote:
> >>
> >>>> currently i'm thinking about the dis-/advantages of moving those
> methods to
> >>>> User (or something like AuthenticatedUser)
> >>> I think this would create complications when we start getting into the
> Identity Management API.  The User object is intended to be a
> self-contained, atomic representation of a single user and isn't intended
> to contain state regarding the user's relationships or membership
> privileges.  It's used in many Identity Management related operations and
> the addition of this extra state would likely be problematic - I'm sure
> Bolek could add more to this.
> >> I support Shane on this. It could lead to a lot of complications and
> not sure what would be benefits of having this.
> >>
> >> Bolek
> >>
> >
>
>

Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Boleslaw Dawidowicz <bo...@gmail.com>.
I like this idea. However my concern is that it will need clear distinction in the IDM API between all roles (including session ones) and persisted roles (identity store level). 

Bolek

On Mar 5, 2012, at 11:45 PM, Shane Bryzak wrote:

> Ok I've been thinking about this over the last few days (and come up with a number of solutions I wasn't happy with), however there is one idea in particular I quite like.  To take a step back for a moment though, the reason we were contemplating adding the extra state to the User class was so that we could convey that state between the authentication process and the user's Identity.  This state (which represents the user's group and role privileges) is then used for the duration of the user's session whenever the Identity.hasRole() or Identity.hasGroup() methods are invoked, to control the user's access to the restricted operations of the application and so forth.
> 
> Until now I believed that the challenge we had was how we integrate the mechanism for this state transfer with the Identity Management API, however I have now come to the conclusion that it should be integrated with the Identity Management API itself, with the IdentityManager bean managing all privilege assignment, both persistent and temporary.  With that in mind, I'd like to propose we add the following methods to the IdentityManager interface:
> 
> grantRoleForSession(User user, Role role);
> grantGroupForSession(User user, Group group);
> 
> We can see these methods in action by building on top of the SimpleAuthenticator example we saw earlier to now include role and group assignment:
> 
> public class SimpleAuthenticator extends BaseAuthenticator implements Authenticator
> {
>    @Inject
>    Credentials credentials;
> 
>    @Inject
>    IdentityManager idm;
> 
>    public void authenticate()
>   {
>        if ("demo".equals(credentials.getUsername()) &&
>                credentials.getCredential() instanceof PasswordCredential &&
>                "demo".equals(((PasswordCredential) credentials.getCredential()).getValue()))
>        {
>            setUser(new SimpleUser("demo"));
>            idm.grantRoleForSession(getUser(), new SimpleRole("ADMIN", "USERS"));
>            idm.grantGroupForSession(getUser(), new SimpleGroup("USERS"));
>            setStatus(AuthenticationStatus.SUCCESS);
>        }
>        else
>        {
>            setStatus(AuthenticationStatus.FAILURE);
>        }
>    }
> }
> 
> This solution is clean, keeps the User class free of additional state and consolidates all user privilege management in one place.  It also opens up a number of exciting possibilities, one such example being session management (manipulation of user privileges at runtime) and makes much easier to implement features such as more complex role assignment such as temporal based (i.e. grant role X to user Y between the hours of 8am and 5pm server time) or expiring (grant role X to user Y for exactly 30 days).  It also means auditing can be performed all in one class.
> 
> 
> 
> On 02/03/12 06:41, Boleslaw Dawidowicz wrote:
>> On Feb 29, 2012, at 10:25 PM, Shane Bryzak wrote:
>> 
>>>> currently i'm thinking about the dis-/advantages of moving those methods to
>>>> User (or something like AuthenticatedUser)
>>> I think this would create complications when we start getting into the Identity Management API.  The User object is intended to be a self-contained, atomic representation of a single user and isn't intended to contain state regarding the user's relationships or membership privileges.  It's used in many Identity Management related operations and the addition of this extra state would likely be problematic - I'm sure Bolek could add more to this.
>> I support Shane on this. It could lead to a lot of complications and not sure what would be benefits of having this.
>> 
>> Bolek
>> 
> 


Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Shane Bryzak <sb...@redhat.com>.
Ok I've been thinking about this over the last few days (and come up 
with a number of solutions I wasn't happy with), however there is one 
idea in particular I quite like.  To take a step back for a moment 
though, the reason we were contemplating adding the extra state to the 
User class was so that we could convey that state between the 
authentication process and the user's Identity.  This state (which 
represents the user's group and role privileges) is then used for the 
duration of the user's session whenever the Identity.hasRole() or 
Identity.hasGroup() methods are invoked, to control the user's access to 
the restricted operations of the application and so forth.

Until now I believed that the challenge we had was how we integrate the 
mechanism for this state transfer with the Identity Management API, 
however I have now come to the conclusion that it should be integrated 
with the Identity Management API itself, with the IdentityManager bean 
managing all privilege assignment, both persistent and temporary.  With 
that in mind, I'd like to propose we add the following methods to the 
IdentityManager interface:

grantRoleForSession(User user, Role role);
grantGroupForSession(User user, Group group);

We can see these methods in action by building on top of the 
SimpleAuthenticator example we saw earlier to now include role and group 
assignment:

public class SimpleAuthenticator extends BaseAuthenticator implements 
Authenticator
{
     @Inject
     Credentials credentials;

     @Inject
     IdentityManager idm;

     public void authenticate()
    {
         if ("demo".equals(credentials.getUsername()) &&
                 credentials.getCredential() instanceof 
PasswordCredential &&
                 "demo".equals(((PasswordCredential) 
credentials.getCredential()).getValue()))
         {
             setUser(new SimpleUser("demo"));
             idm.grantRoleForSession(getUser(), new SimpleRole("ADMIN", 
"USERS"));
             idm.grantGroupForSession(getUser(), new SimpleGroup("USERS"));
             setStatus(AuthenticationStatus.SUCCESS);
         }
         else
         {
             setStatus(AuthenticationStatus.FAILURE);
         }
     }
}

This solution is clean, keeps the User class free of additional state 
and consolidates all user privilege management in one place.  It also 
opens up a number of exciting possibilities, one such example being 
session management (manipulation of user privileges at runtime) and 
makes much easier to implement features such as more complex role 
assignment such as temporal based (i.e. grant role X to user Y between 
the hours of 8am and 5pm server time) or expiring (grant role X to user 
Y for exactly 30 days).  It also means auditing can be performed all in 
one class.



On 02/03/12 06:41, Boleslaw Dawidowicz wrote:
> On Feb 29, 2012, at 10:25 PM, Shane Bryzak wrote:
>
>>> currently i'm thinking about the dis-/advantages of moving those methods to
>>> User (or something like AuthenticatedUser)
>> I think this would create complications when we start getting into the Identity Management API.  The User object is intended to be a self-contained, atomic representation of a single user and isn't intended to contain state regarding the user's relationships or membership privileges.  It's used in many Identity Management related operations and the addition of this extra state would likely be problematic - I'm sure Bolek could add more to this.
> I support Shane on this. It could lead to a lot of complications and not sure what would be benefits of having this.
>
> Bolek
>


Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Boleslaw Dawidowicz <bo...@gmail.com>.
On Feb 29, 2012, at 10:25 PM, Shane Bryzak wrote:

>> 
>> currently i'm thinking about the dis-/advantages of moving those methods to
>> User (or something like AuthenticatedUser)
> 
> I think this would create complications when we start getting into the Identity Management API.  The User object is intended to be a self-contained, atomic representation of a single user and isn't intended to contain state regarding the user's relationships or membership privileges.  It's used in many Identity Management related operations and the addition of this extra state would likely be problematic - I'm sure Bolek could add more to this.

I support Shane on this. It could lead to a lot of complications and not sure what would be benefits of having this.

Bolek


Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Shane Bryzak <sb...@redhat.com>.
On 29/02/12 21:42, Gerhard Petracek wrote:
> hi shane,
>
> imo implementations of Authenticator should be normal cdi beans annotated
> with @Alternative, if they shouldn't be enabled by default (and we can use
> (global) cdi alternatives to allow custom implementations).
> ->  we wouldn't need Identity.authenticatorClass and
> Identity.authenticatorName.

I don't see any advantage in making the Authenticators alternatives, on 
the contrary it creates an additional configuration burden for the 
developer who must then enable the ones they want to use.  It also 
wouldn't alleviate the requirement for Identity.authenticatorClass and 
Identity.authenticatorName as there are use-cases for these, one of 
which I've already mentioned in the sourceforge.net example.

Another example of a use case where Identity.authenticatorClass is 
important was described by a Seam user some time ago - Say your 
application has both a public and private facing user interface; for the 
default, public interface authentication should be performed one way 
using one particular Authenticator implementation, while for the private 
interface the authentication process may be required to use a different 
database table (or some other identity storage) to authenticate against, 
requiring a different Authenticator to be used.  By being able to set 
the specific Authenticator class the login process can control which 
Authenticator is used.  Here's some code to demonstrate:

public @Model class SecurityActions
{
     @Inject Identity identity;

     public void publicLogin()
     {
         identity.setAuthenticatorClass(DefaultAuthenticator.class);
         identity.login();
     }

     public void internalLogin()
     {
         identity.setAuthenticatorClass(InternalAuthenticator.class);
         identity.login();
     }
}

>
> @ AuthenticationStatus.DEFERRED and #postAuthenticate:
> it would be great, if you can provide a source-code example which shows the
> usage.

Here's an example of a deferred authentication from Seam's 
OpenIdAuthenticator:

     public void authenticate()
     {
         OpenIdProvider selectedProvider = getSelectedProvider();
         if (selectedProvider == null)
         {
             throw new IllegalStateException("No OpenID provider has 
been selected");
         }

         OpenIdRelyingPartyApi openIdApi = openIdApiInstance.get();

         List<OpenIdRequestedAttribute> attributes = new 
LinkedList<OpenIdRequestedAttribute>();

         selectedProvider.requestAttributes(openIdApi, attributes);

         openIdApi.login(selectedProvider.getUrl(), attributes, 
getResponse());

         setStatus(AuthenticationStatus.DEFERRED);
     }

In this case, control of the user's browser is handed off to an OpenID 
provider.  Once the user authenticates successfully, they are then 
redirected back to a landing page in your own application which then 
completes the authentication process.

I don't have a specific example for postAuthenticate(), however it could 
be used for any number of things ranging from auditing, to 
post-authentication population of roles and groups in environments where 
loading these resources may be an expensive operation that you may not 
wish to perform until authentication is successful.


>
> @get*Memberships
> currently i'm thinking about the dis-/advantages of moving those methods to
> User (or something like AuthenticatedUser)

I think this would create complications when we start getting into the 
Identity Management API.  The User object is intended to be a 
self-contained, atomic representation of a single user and isn't 
intended to contain state regarding the user's relationships or 
membership privileges.  It's used in many Identity Management related 
operations and the addition of this extra state would likely be 
problematic - I'm sure Bolek could add more to this.
>
> regards,
> gerhard
>
>
>
> 2012/2/28 Shane Bryzak<sb...@redhat.com>
>
>> Following on, here's an extremely basic example of an Authenticator.  If a
>> developer were to simply include this class in their application and
>> perform no further configuration, then it would be used during the
>> authentication process:
>>
>> public class SimpleAuthenticator extends BaseAuthenticator implements
>> Authenticator
>> {
>>     @Inject
>>     Credentials credentials;
>>
>>     public void authenticate()
>>    {
>>         if ("demo".equals(credentials.**getUsername())&&
>>                 credentials.getCredential() instanceof PasswordCredential&&
>>                 "demo".equals(((**PasswordCredential)
>> credentials.getCredential()).**getValue())) {
>>             setStatus(**AuthenticationStatus.SUCCESS);
>>             setUser(new SimpleUser("demo"));
>>         }
>>         else
>>         {
>>             setStatus(**AuthenticationStatus.FAILURE);
>>         }
>>     }
>> }
>>
>> In this example, BaseAuthenticator is an abstract class that implements
>> most of the Authenticator methods and simply allows the subclass to invoke
>> setStatus / setUser / addGroup etc to set the user's authentication state.
>>
>>
>> On 29/02/12 08:15, Shane Bryzak wrote:
>>
>>> With the basic implementation of Identity now in place, it's now a good
>>> time to discuss authentication.  The authentication API comes into play
>>> during the user authentication process, and is responsible for ensuring
>>> that the user is who they claim to be, and providing the application with
>>> the user's assigned role and group privileges.  The authentication API is
>>> not invoked directly by the user, rather it is consumed by the login
>>> process when the user invokes Identity.login().  It should be easily
>>> configured and simple to extend.
>>>
>>> The following code shows the proposed SPI interface for Authenticator, an
>>> implementation of which manages the authentication process:
>>>
>>> public interface Authenticator
>>> {
>>>     public enum AuthenticationStatus {SUCCESS, FAILURE, DEFERRED}
>>>
>>>     void authenticate();
>>>
>>>     void postAuthenticate();
>>>
>>>     AuthenticationStatus getStatus();
>>>
>>>     User getUser();
>>>
>>>     Set<Role>  getRoleMemberships();
>>>
>>>     Set<Group>  getGroupMemberships();
>>> }
>>>
>>> The AuthenticationStatus enum / getStatus() method are used to indicate
>>> the current state of authentication.  Once the authenticate() method has
>>> been invoked and completed, in most cases the getStatus() method will
>>> return a result of SUCCESS or FAILURE, indicating whether the
>>> authentication process was successful or not.  In more complex forms of
>>> Authentication (such as OpenID) the getStatus() method will return an
>>> immediate result of DEFERRED, indicating that the authentication process is
>>> still underway.
>>>
>>> The postAuthenticate() method in most cases will do nothing, however is
>>> provided once again for more complex authentication scenarios.  It allows
>>> the authenticator to perform finalisation of the authentication process,
>>> for example in cases where authentication is asynchronous.
>>>
>>> The last three methods are responsible for providing the user's state to
>>> the Identity bean.  The User instance, along with their role and group
>>> privileges will be used to populate Identity for the duration of the user's
>>> session.
>>>
>>> I propose that we provide the following Authenticator implementations out
>>> of the box:
>>>
>>> 1. IdmAuthenticator - Performs user authentication against the Identity
>>> Management API
>>>
>>> 2. JaasAuthenticator - Allows the user to use an existing JAAS
>>> configuration to authenticate with
>>>
>>> 3. OpenIdAuthenticator - Performs authentication using an OpenID
>>> provider, such as Google
>>>
>>> We can easily extend this list in the future.  I furthermore propose the
>>> following logic to select which Authenticator will be used when invoking
>>> Identity.login(), in descending order of priority:
>>>
>>> 1. If the developer has configured a specific Authenticator
>>> implementation to use by setting Identity.authenticatorClass, then use that
>>> Authenticator.
>>>
>>> 2. If the user has selected a specific authenticator to use by name, by
>>> setting Identity.authenticatorName, then lookup the Authenticator with that
>>> name and use it.  This use case is useful for when you wish to provide
>>> multiple authentication alternatives to the user.  For example, Sourceforge
>>> allows a user to either log in using their Sourceforge username and
>>> password, or with their OpenID account.
>>>
>>> 3. If the developer has provided their own Authenticator implementation,
>>> then use it to authenticate.  This is the simplest use case and allows the
>>> developer to control the authentication process themselves.
>>>
>>> 4. If the Identity Management API has been configured and identity
>>> management services are available, then use IdmAuthenticator to
>>> authenticate the user against the configured identity store.
>>>
>>> This authenticator selection process provides sensible defaults, while
>>> allowing the developer to easily control and/or override the authenticator
>>> configuration.
>>>
>>>
>>>
>>>
>>>


Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Gerhard Petracek <ge...@gmail.com>.
hi shane,

imo implementations of Authenticator should be normal cdi beans annotated
with @Alternative, if they shouldn't be enabled by default (and we can use
(global) cdi alternatives to allow custom implementations).
-> we wouldn't need Identity.authenticatorClass and
Identity.authenticatorName.

@ AuthenticationStatus.DEFERRED and #postAuthenticate:
it would be great, if you can provide a source-code example which shows the
usage.

@get*Memberships
currently i'm thinking about the dis-/advantages of moving those methods to
User (or something like AuthenticatedUser)

regards,
gerhard



2012/2/28 Shane Bryzak <sb...@redhat.com>

> Following on, here's an extremely basic example of an Authenticator.  If a
> developer were to simply include this class in their application and
> perform no further configuration, then it would be used during the
> authentication process:
>
> public class SimpleAuthenticator extends BaseAuthenticator implements
> Authenticator
> {
>    @Inject
>    Credentials credentials;
>
>    public void authenticate()
>   {
>        if ("demo".equals(credentials.**getUsername()) &&
>                credentials.getCredential() instanceof PasswordCredential &&
>                "demo".equals(((**PasswordCredential)
> credentials.getCredential()).**getValue())) {
>            setStatus(**AuthenticationStatus.SUCCESS);
>            setUser(new SimpleUser("demo"));
>        }
>        else
>        {
>            setStatus(**AuthenticationStatus.FAILURE);
>        }
>    }
> }
>
> In this example, BaseAuthenticator is an abstract class that implements
> most of the Authenticator methods and simply allows the subclass to invoke
> setStatus / setUser / addGroup etc to set the user's authentication state.
>
>
> On 29/02/12 08:15, Shane Bryzak wrote:
>
>> With the basic implementation of Identity now in place, it's now a good
>> time to discuss authentication.  The authentication API comes into play
>> during the user authentication process, and is responsible for ensuring
>> that the user is who they claim to be, and providing the application with
>> the user's assigned role and group privileges.  The authentication API is
>> not invoked directly by the user, rather it is consumed by the login
>> process when the user invokes Identity.login().  It should be easily
>> configured and simple to extend.
>>
>> The following code shows the proposed SPI interface for Authenticator, an
>> implementation of which manages the authentication process:
>>
>> public interface Authenticator
>> {
>>    public enum AuthenticationStatus {SUCCESS, FAILURE, DEFERRED}
>>
>>    void authenticate();
>>
>>    void postAuthenticate();
>>
>>    AuthenticationStatus getStatus();
>>
>>    User getUser();
>>
>>    Set<Role> getRoleMemberships();
>>
>>    Set<Group> getGroupMemberships();
>> }
>>
>> The AuthenticationStatus enum / getStatus() method are used to indicate
>> the current state of authentication.  Once the authenticate() method has
>> been invoked and completed, in most cases the getStatus() method will
>> return a result of SUCCESS or FAILURE, indicating whether the
>> authentication process was successful or not.  In more complex forms of
>> Authentication (such as OpenID) the getStatus() method will return an
>> immediate result of DEFERRED, indicating that the authentication process is
>> still underway.
>>
>> The postAuthenticate() method in most cases will do nothing, however is
>> provided once again for more complex authentication scenarios.  It allows
>> the authenticator to perform finalisation of the authentication process,
>> for example in cases where authentication is asynchronous.
>>
>> The last three methods are responsible for providing the user's state to
>> the Identity bean.  The User instance, along with their role and group
>> privileges will be used to populate Identity for the duration of the user's
>> session.
>>
>> I propose that we provide the following Authenticator implementations out
>> of the box:
>>
>> 1. IdmAuthenticator - Performs user authentication against the Identity
>> Management API
>>
>> 2. JaasAuthenticator - Allows the user to use an existing JAAS
>> configuration to authenticate with
>>
>> 3. OpenIdAuthenticator - Performs authentication using an OpenID
>> provider, such as Google
>>
>> We can easily extend this list in the future.  I furthermore propose the
>> following logic to select which Authenticator will be used when invoking
>> Identity.login(), in descending order of priority:
>>
>> 1. If the developer has configured a specific Authenticator
>> implementation to use by setting Identity.authenticatorClass, then use that
>> Authenticator.
>>
>> 2. If the user has selected a specific authenticator to use by name, by
>> setting Identity.authenticatorName, then lookup the Authenticator with that
>> name and use it.  This use case is useful for when you wish to provide
>> multiple authentication alternatives to the user.  For example, Sourceforge
>> allows a user to either log in using their Sourceforge username and
>> password, or with their OpenID account.
>>
>> 3. If the developer has provided their own Authenticator implementation,
>> then use it to authenticate.  This is the simplest use case and allows the
>> developer to control the authentication process themselves.
>>
>> 4. If the Identity Management API has been configured and identity
>> management services are available, then use IdmAuthenticator to
>> authenticate the user against the configured identity store.
>>
>> This authenticator selection process provides sensible defaults, while
>> allowing the developer to easily control and/or override the authenticator
>> configuration.
>>
>>
>>
>>
>>
>

Re: [DISCUSS] DELTASPIKE-76 Authentication API

Posted by Shane Bryzak <sb...@redhat.com>.
Following on, here's an extremely basic example of an Authenticator.  If 
a developer were to simply include this class in their application and 
perform no further configuration, then it would be used during the 
authentication process:

public class SimpleAuthenticator extends BaseAuthenticator implements 
Authenticator
{
     @Inject
     Credentials credentials;

     public void authenticate()
    {
         if ("demo".equals(credentials.getUsername()) &&
                 credentials.getCredential() instanceof 
PasswordCredential &&
                 "demo".equals(((PasswordCredential) 
credentials.getCredential()).getValue())) {
             setStatus(AuthenticationStatus.SUCCESS);
             setUser(new SimpleUser("demo"));
         }
         else
         {
             setStatus(AuthenticationStatus.FAILURE);
         }
     }
}

In this example, BaseAuthenticator is an abstract class that implements 
most of the Authenticator methods and simply allows the subclass to 
invoke setStatus / setUser / addGroup etc to set the user's 
authentication state.

On 29/02/12 08:15, Shane Bryzak wrote:
> With the basic implementation of Identity now in place, it's now a 
> good time to discuss authentication.  The authentication API comes 
> into play during the user authentication process, and is responsible 
> for ensuring that the user is who they claim to be, and providing the 
> application with the user's assigned role and group privileges.  The 
> authentication API is not invoked directly by the user, rather it is 
> consumed by the login process when the user invokes Identity.login().  
> It should be easily configured and simple to extend.
>
> The following code shows the proposed SPI interface for Authenticator, 
> an implementation of which manages the authentication process:
>
> public interface Authenticator
> {
>     public enum AuthenticationStatus {SUCCESS, FAILURE, DEFERRED}
>
>     void authenticate();
>
>     void postAuthenticate();
>
>     AuthenticationStatus getStatus();
>
>     User getUser();
>
>     Set<Role> getRoleMemberships();
>
>     Set<Group> getGroupMemberships();
> }
>
> The AuthenticationStatus enum / getStatus() method are used to 
> indicate the current state of authentication.  Once the authenticate() 
> method has been invoked and completed, in most cases the getStatus() 
> method will return a result of SUCCESS or FAILURE, indicating whether 
> the authentication process was successful or not.  In more complex 
> forms of Authentication (such as OpenID) the getStatus() method will 
> return an immediate result of DEFERRED, indicating that the 
> authentication process is still underway.
>
> The postAuthenticate() method in most cases will do nothing, however 
> is provided once again for more complex authentication scenarios.  It 
> allows the authenticator to perform finalisation of the authentication 
> process, for example in cases where authentication is asynchronous.
>
> The last three methods are responsible for providing the user's state 
> to the Identity bean.  The User instance, along with their role and 
> group privileges will be used to populate Identity for the duration of 
> the user's session.
>
> I propose that we provide the following Authenticator implementations 
> out of the box:
>
> 1. IdmAuthenticator - Performs user authentication against the 
> Identity Management API
>
> 2. JaasAuthenticator - Allows the user to use an existing JAAS 
> configuration to authenticate with
>
> 3. OpenIdAuthenticator - Performs authentication using an OpenID 
> provider, such as Google
>
> We can easily extend this list in the future.  I furthermore propose 
> the following logic to select which Authenticator will be used when 
> invoking Identity.login(), in descending order of priority:
>
> 1. If the developer has configured a specific Authenticator 
> implementation to use by setting Identity.authenticatorClass, then use 
> that Authenticator.
>
> 2. If the user has selected a specific authenticator to use by name, 
> by setting Identity.authenticatorName, then lookup the Authenticator 
> with that name and use it.  This use case is useful for when you wish 
> to provide multiple authentication alternatives to the user.  For 
> example, Sourceforge allows a user to either log in using their 
> Sourceforge username and password, or with their OpenID account.
>
> 3. If the developer has provided their own Authenticator 
> implementation, then use it to authenticate.  This is the simplest use 
> case and allows the developer to control the authentication process 
> themselves.
>
> 4. If the Identity Management API has been configured and identity 
> management services are available, then use IdmAuthenticator to 
> authenticate the user against the configured identity store.
>
> This authenticator selection process provides sensible defaults, while 
> allowing the developer to easily control and/or override the 
> authenticator configuration.
>
>
>
>