Yeah, the API and class design Undertow uses is rather neat indeed. It's
much closer to JASPIC + LoginModules than to Servlet Filters + CDI
producers, but it definitely has a more modern touch.
(*Something to think about is that Undertow when faced with the need for a
security system *again* choose to build its own one. It's a very nice one,
nothing against that, but it's yet another option.*)
phases. In this example Undertow chooses events.
Indeed, Undertow chooses events but using its own API. No CDI is involved
at that level. Although Undertow is build in such a way that CDI can be
(and is) initialized before auth modules are invoked. Because of that it's
so trivial in Undertow to bridge their native events to CDI ones.
I'd personally say that Undertow has made the right decision to use events
instead of phases or something else, but I'm also aware that I'm not fully
up to date with all pros and cons of both approaches.
My concern is about spreading CDI to other specifications. Security
being
a brand new one, I wonder if this new spec had something like that in mind.
Other specs might use events handling and, therefore, use the CDI event
mechanism for it. If they do want to use events, the question is "should
they define there own events or phases ?".
I hear you.
The thing is that the Security API cannot really throw the event directly
itself, but has to ask the containers that actually log a user in to do so
(e.g. the Servlet, EJB and JCA containers). This is something that is
perhaps not entirely clear to everyone, but something like JASPIC too is
not a separate implementation. There is no JASPIC RI jar that you download
and add to your project. Instead, there's a Servlet Container Profile,
which compatible Servlet containers (e.g. Undertow) then implement.
So if the login/logout events are to be published via CDI, then effectively
Servlet containers have to use CDI.
While I don't want to rule this out, especially if there's wording in the
spec like: "If CDI is available in the environment, the event should be
published via CDI's eventing mechanism", it's a slightly more complicated
task politically speaking than just the Security API deciding to use CDI.
Another option is that Servlet uses their native event mechanism
(@WebListener + a new interface, say ServletAuthListener) and that the
Security API installs a default listener that bridges this event to CDI.
Kind regards,
Arjan Tijms
On Tue, Dec 23, 2014 at 2:44 PM, Antonio Goncalves <
antonio.goncalves(a)gmail.com> wrote:
Arjan, I really like what Undertow does, and that was exactly my question
: should it through specific events or phases. In this example Undertow
chooses events.
My concern is about spreading CDI to other specifications. Security being
a brand new one, I wonder if this new spec had something like that in mind.
Other specs might use events handling and, therefore, use the CDI event
mechanism for it. If they do want to use events, the question is "should
they define there own events or phases ?". Just trying to find common
patterns to spread the word on other specs.
Antonio
On Tue, Dec 23, 2014 at 1:44 PM, arjan tijms <arjan.tijms(a)gmail.com>
wrote:
> Hi,
>
> On Tue, Dec 23, 2014 at 10:03 AM, Mark Struberg <struberg(a)yahoo.de>
> wrote:
> > Switching languages is a business concern in some companies.
>
> I think you're right and it is, but I still don't really see what it
> has to do with communicating the authentication details to the
> container.
>
>
> > And the example with the role switching was just ONE example. There are
> dozen others. Now you could go on and add all those things into a next spec
> adding another 450++ classes. But no one gonna use that!
>
> Sorry, but I really don't understand your concern. There are only two
> pieces of information to be communicated:
>
> 1. The caller principal name
> 2. The groups (roles)
>
> That's all.
>
> Things like language switching, the number of posts a user gets to see
> on the front page of your site, the background color and what have you
> just aren't related.
>
> There are no 450 classes needed and none of those dozens of other
> examples have to be added to the spec. It's just different variants of
> communicating that caller principal name and groups.
>
> The only thing that was asked for here to be added are two events:
>
> 1. User logs in (i.e. caller principal and groups are applied by the
> container)
> 2. User logs out (i.e. caller principal and groups are removed by the
> container)
>
> Then Antonio wondered about one variant of that; the just-before event
> and whether there's any notion of a "during".
>
> Undertow for instance already throws these events, and they can be
> easily bridged to CDI events. See
>
http://jdevelopment.nl/bridging-undertows-authentication-events-cdi
>
> Kind regards,
> Arjan Tijms
>
>
>
>
>
>
>
> >
> >
> > LieGrue,
> > strub
> >
> >
> >
> >
> >
> >> On Monday, 22 December 2014, 22:55, arjan tijms
<arjan.tijms(a)gmail.com>
> wrote:
> >> > Hi,
> >>
> >> On Mon, Dec 22, 2014 at 8:54 PM, Mark Struberg <struberg(a)yahoo.de>
> wrote:
> >>> To be honest I'm not sure if I'd do any of this. All this
should
> >> imo not belong to the EE spec at all. It is probably just far too
> business
> >> specific.
> >>
> >> What exactly should not be done? Authentication events, or the
> >> enumeration Antonio mentioned?
> >>
> >>
> >>> What if the application needs some kind of role change. E.g. you
> >> temporarily switch roles, change the preferred language, etc? All
> these things
> >> are heavily depending on the application and are not technical at all.
> >>
> >> I'm not sure what the preferred language has to do with this. This is
> >> not an authentication concern, but simply a user preference and indeed
> >> an application concern.
> >>
> >> Switching roles however is an authentication concern. It's IMHO not
> >> business specific. There are two variations, a temporarily one as you
> >> mention, and a "permanent" one (permanent within a session, or as
> >> authentication in Java EE is by default per request, even do this for
> >> just the remainder of the request).
> >>
> >> The temporary one can be implemented via authentication stacks, and
> >> this can definitely be implemented in a completely non business
> >> specific way. In a declarative way @RunAs already does this in a way.
> >> A programmatic API could look like the following:
> >>
> >> request.authenticateStacked(); // Starts new authentication dialog, if
> >> authenticated previous identity is stored on stack
> >> request.authenticateStackedAs(String username); // Programmatic
> >> equivalent of @RunAs
> >> request.authenticateStacked(Callback... callbacks); // Generic
> >> variant, supporting extendible options such as adding/removing roles
> >> request.logoutCurrent(); // logs out current user, goes back one level
> >> on the stack
> >> request.logout(); // existing API, totally logs user out
> >>
> >> A "permanent" change is typical when for instance a username is
linked
> >> to a user email, and the user changes his email. The act of changing
> >> this email is application specific, but just signaling this change to
> >> the container is a general action (see
> >>
https://java.net/jira/browse/JASPIC_SPEC-22).
> >>
> >> Events can be largely orthogonal to all of this, although perhaps some
> >> properties of the event could give information about the authenticate
> >> type (new one, or stacked one).
> >>
> >> Kind regards,
> >> Arjan Tijms
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >>>
> >>> LieGrue,
> >>> strub
> >>>
> >>>
> >>>
> >>> On Monday, 22 December 2014, 20:12, arjan tijms
> >> <arjan.tijms(a)gmail.com> wrote:
> >>>
> >>>
> >>>>
> >>>>
> >>>> Hi,
> >>>>
> >>>> On Monday, December 22, 2014, Antonio Goncalves
> >> <antonio.goncalves(a)gmail.com> wrote:
> >>>>
> >>>> Hi all,
> >>>>>
> >>>>>
> >>>>>
> >>>>> The CDI spec defines the "Transactional observer
methods"
> >> (§10.4.5) with a TransactionPhase :
> >>>>>
> >>>>>
> >>>>> public enum TransactionPhase {
> >>>>> IN_PROGRESS,
> >>>>> BEFORE_COMPLETION,
> >>>>> AFTER_COMPLETION,
> >>>>> AFTER_FAILURE,
> >>>>> AFTER_SUCCESS
> >>>>> }
> >>>>>
> >>>>>
> >>>>> void onDocumentUpdate(@Observes(during=AFTER_SUCCESS) @Updated
> >> Document doc) { ... }
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>> Now that there is a new Security specification coming along, it
> >> would be helpful to be able to observe before/after the user logs-in or
> >> logs-out, for example. First I thought "well, the Security spec
> defines a
> >> set of events, fires them, and we just have to observe them". But what
> >> about the "during" phase ? What would make more sense in such use
case
> >> ? Using the same "during" mechanism or events ?
> >>>>
> >>>>
> >>>> I think separate events may be better.
> >>>>
> >>>>
> >>>> Maybe I'm mistaken but the way I think the transactional events
are
> >> used is that during a transactional method an event is fired. The
> event is then
> >> not delivered right away to all observers, but for those using
> >> during=after_success only when the TX commits. This is kinda like what
> JMS does;
> >> a message is only send when the TX commits, or send right away. CDI
> offers 3
> >> other cases, but I feel that those first two are the main ones.
> >>>>
> >>>>
> >>>> For authentication events I don't think we can really speak of
a
> >> "logging-in" method. Even if we would appoint one (e.g.
> >> validateRequest() in a SAM) then I'm not sure whether any random event
> >> published during that method would have any need to be queued until
> just before
> >> or after authentication actually happens.
> >>>>
> >>>>
> >>>> Instead, we would merely be interested in the actual events; the
> moment
> >> the container is about to authenticate (so we can potentially veto)
> and the
> >> moment right after that (so we can take an action such as loading data
> related
> >> to the user into the current session).
> >>>>
> >>>>
> >>>> Just my 2 cents. Hope I understood the case correctly.
> >>>>
> >>>>
> >>>> Kind regards,
> >>>> Arjan
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>>
> >>>>> public enum LoginPhase {
> >>>>> BEFORE_LOGIN,
> >>>>> AFTER_LOGIN,
> >>>>> BEFORE_LOGOUT,
> >>>>> AFTER_LOGOUT,
> >>>>> }
> >>>>>
> >>>>>
> >>>>> void onLogout(@Observes(during=BEFORE_LOGOUT) User user) { ...
> >> }
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>> Any thoughts ?
> >>>>>
> >>>>> --
> >>>>>
> >>>>> Antonio Goncalves
> >>>>> Software architect, Java Champion and Pluralsight author
> >>>>>
> >>>>> Web site | Twitter | LinkedIn | Pluralsight | Paris JUG |
Devoxx
> >> France
> >>>>
> >>>> _______________________________________________
> >>>> cdi-dev mailing list
> >>>> cdi-dev(a)lists.jboss.org
> >>>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
> >>>>
> >>>> Note that for all code provided on this list, the provider licenses
> the
> >> code under the Apache License, Version 2
> >> (
http://www.apache.org/licenses/LICENSE-2.0.html). For all other
> ideas provided
> >> on this list, the provider waives all patent and other intellectual
> property
> >> rights inherent in such information.
> >>>>
> >>>>
> >>
>
--
Antonio Goncalves
Software architect, Java Champion and Pluralsight author
Web site <
http://www.antoniogoncalves.org> | Twitter
<
http://twitter.com/agoncal> | LinkedIn
<
http://www.linkedin.com/in/agoncal> | Pluralsight
<
http://pluralsight.com/training/Authors/Details/antonio-goncalves> | Paris
JUG <
http://www.parisjug.org> | Devoxx France <
http://www.devoxx.fr>