I implemented almost the same exact interceptor for security purposes
myself.

If the goal is to get away from extending classes, which it is, then I would
say interceptors sound like a better choice. I prefer composition over
inheritance.

On 3/23/06, Mike Snare <[EMAIL PROTECTED]> wrote:
>
> > >I can tell tapestry that the default base page is this page, but then
> > >pages that don't otherwise need a page class at all AND don't need the
> > >security check have to create a page class that extends BasePage just
> > >to avoid the security check.  Seem pointless.
> > >
> > >
> > OK, I think I see your point. You have a lot of pages with no page
> > class(?). In the Tapestry app's I've developed so far, most pages tend
> > to need a class anyway (if not an individual class, at least an
> > app-specific base class), so marking them with a meta annotation or
> > having them extend the appropriate base class has never involved any
> > significant effort. In the relatively huge app I'm working on now, all
> > pages (except Login) are protected so my situation is probably similar
> > to yours.
>
> To be honest, I don't have a lot of pages yet at all as the app is
> still very early in development (but I concede that most will need a
> base class).  I'm thinking in general terms.  There will be some that
> I can think of that probably won't need a base class, and for some of
> _those_, I can foresee skipping authentication.
>
> It just seems like recognition of a need for an application-specific
> base class is really an indication that what you have are
> cross-cutting concerns or common functionality.  Both of these can be
> achieved without forcing a new base class.
>
> > If I had a significant number of pages that didn't need their own class,
> > I would use the default base page solution you referred to. The base
> > class approach would start to break down in the last scenario you
> > mentioned (pages that don't otherwise need a page class at all AND don't
> > need the security check have to create a page class that extends
> > BasePage just to avoid the security check). However, it doesn't sound
> > like your app falls into this category (you said nearly every page is
> > protected) and I've found that most apps are either primarily protected
> > or primarily unprotected, so there is always a logical default base
> > class. In addition, your anonymous pages don't need to have a class to
> > avoid the security check, they would only need a page spec with a meta
> tag.
>
> Hadn't thought of meta tags.  +1 to that.
>
> > >Another issue is that of enforcement.  If a developer needs to
> > >implement the pageAttach method they need to remember to call
> > >super.pageAttach first.  Alternatively, I can make the pageAttach
> > >method final in the base class to eliminate the potential security
> > >bugs and redirect to a new method (say, realPageAttach) that needs to
> > >be overridden by pages that need that callback -- except, again, for
> > >those classes that don't need authentication, which should extend
> > >directly from BasePage and implement PageAttachedListener and
> > >implement the method themselves.  Seems alot for people to have to
> > >remember just to use the authentication features correctly.
> > >
> > >
> > pageAttach? Does pageValidate() not get invoked if pageAttach is
> > overridden? Since it's critical that pageValidate be invoked for my
> > authentication to function properly, I'm very interested in hearing
> > about this or any other pitfalls that would cause pageValidate to be
> > ignored.
>
> Sorry, take everything I said about pageAttach and pretend I said
> pageValidate (it's what I meant).  The same still applies.
>
> > >Even if the logic exists in the base class, the callback issue remains
> > >the same.  Pages that want to be callbackable will have to implement
> > >some method that I can call from the base class to get the parameter
> > >array.  That would lead to code of the following ilk, which seems odd
> > >at the very least (if it will even work).
> > >
> > >if (this instanceof IParamProvidingCallback) {
> > >  IParamProvidingCallback ppcb = (IParamProvidingCallback) this;
> > >  Obect[] params = ppcb.getParamArray();
> > >  // use my param array to create an ExternalCallback
> > >}
> > >
> > >
> > Ouch - no, I wouldn't go for that. More like this (superclass for "view"
> > pages) :
> >
> > public abstract class BaseViewPage extends AppBasePage implements
> > IExternalPage {
> >
> >  /**
> >   * Gets the id of the item being viewed.
> >   *
> >   * @return item id
> >   */
> >  @Persist
> >  public abstract Integer getItemId();
> >
> >  /**
> >   * Gets the callback for this page.
> >   *
> >   * @return callback for this page
> >   */
> >  @Override
> >  public ICallback getPageCallback() {
> >    Object[] parameters = new Object[1];
> >    parameters[0] = getItemId();
> >    return new ExternalCallback( getPageName(), parameters );
> >  }
> > }
> >
> > Page subclasses can override getPageCallback() to include their specific
> > parameters and create the correct type of callback. With the service
> > interceptor approach, don't you still have to define callbacks per page
> > if you want specific parameters included and if you want specific types
> > of callbacks, or do you have generic solution that packages all page
> > parameters and figures out if it should create an External, Direct or
> > Page callback?
>
> Nope, the pages would still have to implement some method to package
> the parameters.  It would be pretty easy to determine whether or not
> to create a page, direct, or external callback for a particular
> request, it's only the parameters that are an issue.  That said, I
> think your approach on this particular issue is better than creating
> the callback in the interceptor and it also skirts the issue of
> needing to care what kind of callback to create in the interceptor..
> +1
>
> > >As to the duplication of hivemind configurations, there are 5 services
> > >to which I am contributing an interceptor factory (by reference,
> > >anyway) and there are significantly more pages that need protection.
> > >I'm not really worried about *that* duplication.
> > >
> > >If I can get callbacks to work with the fix that Jesse said he'll look
> > >into (thanks again) than I see this as a significant improvement to
> > >what people would look at as the 'standard' approach to authentication
> > >for tapestry frameworks.  It's a much, much better separation of
> > >concerns.
> > >
> > >
> > Couldn't you make the same "seperation of concerns" argument for
> > performing authentication in the container via URL mapping? Seperating
> > concerns is well and good, but it's in line with modern security
> > practices to define security on the object being secured rather than at
> > a higher level (each approach has its advantages and disadvantages,
> > somewhat akin to RBAC vs MAC). Obviously the security monitor itself
> > should be separated from the objects being secured, but there's nothing
> > wrong with bringing the hooks down closer to the objects.
>
> Nope.  Nothing wrong with it at all.  As with any problem there are
> many approaches to finding a solution.  This one 'speaks' to me
> because individual developers get to worry about it less, and I'm not
> forcing a base class.  That was something I didn't like about struts
> (the base class with re-directed final methods from Action).
>
> As to the issue of 'defining security on the object being secured' I
> don't see your approach as much different than mine.  Your approach
> just comes later in the request cycle.  I might just as well say that
> what I am securing is the service (which is technically true) and not
> the page.
>
> > >I appreciate the input, but the base page approach just isn't workable.
> > >
> > >
> > *cough*, well, it actually works just fine because it's been the
> > standard approach in Tapestry since at least 3.0 ;)
> > Anyway, I certainly don't *mind* having an alternate place to hook
> > authentication into Tapestry and I think a lot of people would agree
> > with you that it should be as seperate a concern as possible. I just
> > think that if you pursued a strategy using pageValidate, base classes
> > and normal, clean OO design, you wouldn't think the result was bad
> > practice or unworkable.
>
> Ok, perhaps 'workable' isn't the word I meant there.  Clearly it
> works, and many are using it but it requires a base class which I
> don't want.  Tapestry itsself has a goal (I read it somewhere -- I
> think on Howard's blog) of not having any base classes for pages and
> components.  In line with this, I'm trying to avoid arbitrarily adding
> base class overhead for the sake of functionality that can be achieved
> elsewhere.  I'll switch 'workable' with 'desirable' (much like
> JBuilder in that regard, it works, but do you really want to use it?).
>
> The interceptor has the additional benefit of being able to secure
> home grown services (like download services) not provided by tapestry
> that have no concept of a page at all.  It's an interceptor, and can
> be used to authenticate any service.
>
> All good comments.  Please continue poking holes.  I'm not so stubborn
> as to refuse to see better ways of doing things, it's just that for
> now I still prefer my way.
>
> Thanks,
> -Mike
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>


--
Jesse Kuhnert
Tacos/Tapestry, team member/developer

Open source based consulting work centered around
dojo/tapestry/tacos/hivemind.  http://opennotion.com

Reply via email to