Mike Snare wrote:

I originally did use a base page, but decided against it for a number
of reasons.

The first is that nearly all pages in the app are protected (it's a
management app), so nearly every page would need to extend this base
class just to get this otherwise free feature.  I don't really like
that.
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.

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.

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.

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?

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.

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.

-Ryan


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to