deltaspike-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gerhard Petracek <gerhard.petra...@gmail.com>
Subject Re: [DISCUSS] DELTASPIKE-76 Authentication API
Date Wed, 29 Feb 2012 22:36:54 GMT
@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 <sbryzak@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<sbryzak@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.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message