Hi,

The logical page name is available in the parameters passed to your filter. You can then use the ComponentSource to get at the actual class using the logical page name and extract whatever info you'd like - I use this service along with annotations on my page classes:

public class PageAccessCheckerImpl
    implements PageAccessChecker {

  private final SecurityService securityService;
  private final ComponentSource componentSource;

public PageAccessCheckerImpl(SecurityService securityService, ComponentSource componentSource) {
    this.securityService = securityService;
    this.componentSource = componentSource;
  }

  public void checkPageAccess(PageRenderRequestParameters parameters) {
    checkPageAccess(parameters.getLogicalPageName());
  }

  public void checkPageAccess(ComponentEventRequestParameters parameters) {
    checkPageAccess(parameters.getActivePageName());
  }

  private void checkPageAccess(String pageName) {
    Component page = componentSource.getPage(pageName);
    Secured secured = page.getClass().getAnnotation(Secured.class);

    if (null == secured) return;
if (!securityService.isUserLoggedIn()) throw new LoginRequiredException(); if (!securityService.isUserInRole(secured.value())) throw new AccessForbiddenException();
  }
}

I then handle the exceptions in my handlers and redirect to another page if necessary.

-Filip

Andreas Pardeike skrev:
Hi,

I have implemented my access control as below (I also tried contributeRequestHandler)
but my main problem is that I have a couple of public pages.

I can't see how I could get the current page from within

public boolean dispatch(Request request, Response response)
or
public boolean service(Request request, Response response, RequestHandler handler)

unless I rely on the rather unsafe way to use request.getPath(). Is there
a way to get the current page/component/service that is the target of the
request and *ask* it if it is public?

/Andreas Pardeike


On 28 sep 2007, at 15.40, Howard Lewis Ship wrote:

The logic used by the IoC container is the same whether its injecting via a
service binder method or by the constructor of the implementation class.

On 9/28/07, Chris Lewis <[EMAIL PROTECTED]> wrote:

The only interface I implement is Dispatcher, so all should be good.
Thanks for the pointer on bind() - I will use it. Will I then need to
use @Inject/@InjectService in my constructor, or will the container
"see" the needed arguments?

Howard Lewis Ship wrote:
Looks pretty reasonable to me.

You're building the hard way:

public static void bind(ServiceBinder binder) {
 binder.bind(Dispatcher.class, SingletonAccessControllerImpl.class
).withId("AccessController");
}

The only other issue (I'd have to check) is to ensure that the
interfaces
you are implementing are all public, not internal.

On 9/27/07, Chris Lewis <[EMAIL PROTECTED]> wrote:

Hi Ben,

I asked a question like this some time ago, and I've made some good
progress like this. I have the same basic requirements as you and
specifically do not want my pages to deal with
authentication/restriction AT ALL. I did some reading about request
handling as well as digging through the source (specifically
TapestryModule) and realized I should be able to achieve this by
contributing a Dispatcher to the MasterDispatcher service, such that it
sits before the render and action dispatchers. My attention has been
temporarily diverted so I haven't worked on it the last few days, but
here's the basic code for I've done so far.

In my app module:

   public Dispatcher buildAccessController(
       Map<String, String> configuration,
       @InjectService("ApplicationStateManager")
ApplicationStateManager asm
       ) {
       return new SingletonAccessControllerImpl(configuration, asm);
   }

   public void
contributeMasterDispatcher(OrderedConfiguration<Dispatcher>
configuration,
       @InjectService("AccessController") Dispatcher accessControl) {
       configuration.add("AccessController", accessControl,
"before:PageRender");
   }

I intend to use ApplicationStateManager to grab client/session/request
specific ASOs (namely a User/permissions object), so I can use a
singleton access controller and still access user-specific data. The
contribution puts my dispatcher ahead of the page and action
dispatchers. AFAIK this is not in the docs but its quite clear in the
TapestryModule.

And here is my (test) dispatch implementation:

   public boolean dispatch(Request request, Response response) throws
IOException {
       boolean canAccess = true;

       //...Access control logic using the ApplicationStateManager

       return ! canAccess;
   }

The inverted return will halt processing of the request if canAccess is true (see docs/src for Dispatcher). Throwing a kind of access exception
would probably do the trick as well.

I hope this helps, and if you make good progress do share.

Also, Howard if you see anything obviously wrong or "bad" with this
method, please share :-).

chris

Ben Tomasini wrote:

Hi,

I am working on an application that requires a logged in user for
access

to

any of the pages.  My plan is to create a login form and store the

logged in

user in an ASO.  I understand that I can implement an onActivate() on

each

of my pages, check to see if the user exists in the ASO, and if not,
redirect the user to the login page.  I could put this method into an
abstract page which all of my pages extend from; however, I would
rather

not

put that kind of constraint and burden on page development.

Is there a more global way to enforce that an ASO exists, and if not,
redirect to a page?

Ben



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










--
Howard M. Lewis Ship
Partner and Senior Architect at Feature50

Creator Apache Tapestry and Apache HiveMind


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



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

Reply via email to