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 <[email protected]> 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 <[email protected]>
> 
>> 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<[email protected]>
>>> 
>>> 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.
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>> 

Reply via email to