You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Charles Mason <ch...@gmail.com> on 2007/08/24 22:40:03 UTC

[T5] Restricting Page Access

Firstly I just want to say Tapestry 5 is amazing, Tapestry 4 was very
good but Tapestry 5 is outstanding. One thing I haven't figured out
how to do the Tapestry 5 way is controlling page access.

On many sites I write there is often a need to password protect a
large number of pages. The way I usually do it in Tapestry 4 was to
put an object in the application state once the user logged in. Then
every restricted page was a sub class of my RestrictedPage class. The
RestrictedPage class was a subclass of Page, which when activated
check the existence of the Application Sate Object. If the user wasn't
logged in there was no application state object they weren't logged
in.

I have been trying to do a similar thing in Tapestry 5, my first
problem was that I couldn't get all of the annotations and special
methods (like onActivate) to work if declared in the base class
RestrictedPage. The same code worked fine in the actual page class,
however I don't really want a big chunk of identical code in every
class of a restricted page, as that would make future changes to the
login system difficult. I assume its a feature rather than a bug that
these annotations and special methods don't work if defined in the
base class.

I was looking at various solutions to this and found the Tapestry 5
acegi library, http://www.localhost.nu/java/tapestry5-acegi/ It has a
really nice secured annotation to do a similar thing e.g.

@Secured("ROLE_ADMIN")
public class AdminPage
{
}

I was wondering how this worked. I am assuming its through some sort
of T5 service. I was looking at the documentation on the T5 site,
although I can't figure how to do something like that. I also had a
look at the Tapestry 5 acegi library. But not knowing acegi, its hard
to see how this works in the source.

I was wondering if someone could tell me the basic principle of what I
need to write or implement to be able to hook in the to the page
loading procedure  from just an annotation.


Charlie M

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: [T5] Restricting Page Access

Posted by Charles Mason <ch...@gmail.com>.
On 8/25/07, Nick Westgate (Work) <ni...@key-planning.co.jp> wrote:
>
> Also, just as a reminder, base classes must not go in the pages package.
>

I thinks that's where my RistrictedPage class was going wrong. I think
I will play around with trying to create some tapestry5-acegi like
annotations and request filters.

ACEGI I think is a bit more than I need. However I use the same base
login / user management package I created for a few sites, so I think
it would pay to get the restricting of pages right for all the new
Tapestry 5 versions. Plus its a good exercise in learning some of the
more complicated bits of Tapestry 5.

Thanks for all, the help.

Charlie M

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: [T5] Restricting Page Access

Posted by "Nick Westgate (Work)" <ni...@key-planning.co.jp>.
Also, just as a reminder, base classes must not go in the pages package.

Cheers,
Nick.



César Les wrote:
> 
> A little mistake .... myPage MUST extends SecurePage of course.... :)
> 
> On 8/24/07, César Lesc <ce...@gmail.com> wrote:
>> If you have a base class for your protected pages then onActivate
>> event will trigger first on the parent then in the child if return
>> value of the parent onActivate event is null. This work fine in my
>> project, I don´t use any annotation for this just declare:
>>
>> public abstract class SecurePage{
>>
>>    Class onActivate(){
>>        // check security return null if ok
>>    }
>> }
>>
>>
>> then
>>
>> public class myPage{
>>
>> void onActivate(){
>>
>>    // do something
>> }
>>
>> }
>>
>>
>> Regards
>>
>> César.
>>
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/-T5--Restricting-Page-Access-tf4325658.html#a12321896
Sent from the Tapestry - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: [T5] Restricting Page Access

Posted by César Lesc <ce...@gmail.com>.
A little mistake .... myPage MUST extends SecurePage of course.... :)

On 8/24/07, César Lesc <ce...@gmail.com> wrote:
> If you have a base class for your protected pages then onActivate
> event will trigger first on the parent then in the child if return
> value of the parent onActivate event is null. This work fine in my
> project, I don´t use any annotation for this just declare:
>
> public abstract class SecurePage{
>
>    Class onActivate(){
>        // check security return null if ok
>    }
> }
>
>
> then
>
> public class myPage{
>
> void onActivate(){
>
>    // do something
> }
>
> }
>
>
> Regards
>
> César.
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: [T5] Restricting Page Access

Posted by César Lesc <ce...@gmail.com>.
If you have a base class for your protected pages then onActivate
event will trigger first on the parent then in the child if return
value of the parent onActivate event is null. This work fine in my
project, I don´t use any annotation for this just declare:

public abstract class SecurePage{

   Class onActivate(){
       // check security return null if ok
   }
}


then

public class myPage{

void onActivate(){

   // do something
}

}


Regards

César.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: [T5] Restricting Page Access

Posted by Robin Helgelin <lo...@gmail.com>.
On 8/28/07, Erik Vullings <er...@gmail.com> wrote:
> To clarify my understanding - how does it deal with protecting
> links/functions. For example, assume I'm a regular, non-admin user and
> access the application. Since I'm not an admin, I don't see the link to the
> "Clear database" function, but somehow, I can guess it's link. How does the
> framework protect me from invoking that link anyways? Do you have equivalent
> functions as ifLoggedIn and ifRole in the java class files?

Yes, just use the @Secured("ROLE_ADMIN") annotation on the page class
and the framework takes care of the rest.

-- 
        regards,
        Robin

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: [T5] Restricting Page Access

Posted by Erik Vullings <er...@gmail.com>.
That's really cool and very useful!

To clarify my understanding - how does it deal with protecting
links/functions. For example, assume I'm a regular, non-admin user and
access the application. Since I'm not an admin, I don't see the link to the
"Clear database" function, but somehow, I can guess it's link. How does the
framework protect me from invoking that link anyways? Do you have equivalent
functions as ifLoggedIn and ifRole in the java class files?

Cheers
Erik

On 8/27/07, Robin Helgelin <lo...@gmail.com> wrote:
>
> On 8/27/07, Erik Vullings <er...@gmail.com> wrote:
> > Hi,
> >
> > Just wondering - when dealing with page authorizations, does this model
> > expand to component authorizations, i.e. you may visit the page, but not
> > certain components (redirect to another component), or you can see a
> > component, but with less privileges (e.g. view but not edit). In other
> > words, how would you deal with CRUD (create, read, update, delete)
> > role-based authorization on a component level?
>
> I'd say it's up to the component. I've just added two new components
> in tapestry5-acegi, called IfLoggedIn and IfRole, which can be used in
> components such as:
>
> <t:security.ifloggedin>
>         You are logged in, welcome!
>         <t:security.ifrole role="ROLE_ADMIN">
>                 You are even logged as admin, cool!
>                 <t:parameter name="else">
>                         Sorry, you don't have admin credentials.
>                 </t:parameter>
>         </t:security.ifrole>
>         <a t:type="actionlink" t:id="logout">Logout</a>
>         <t:parameter name="else">
>                 Not logged in, please <t:pagelink
> t:page="LoginPage">do</t:pagelink>.
>         </t:parameter>
> </t:security.ifloggedin>
>
> --
>         regards,
>         Robin
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: [T5] Restricting Page Access

Posted by Robin Helgelin <lo...@gmail.com>.
On 8/27/07, Erik Vullings <er...@gmail.com> wrote:
> Hi,
>
> Just wondering - when dealing with page authorizations, does this model
> expand to component authorizations, i.e. you may visit the page, but not
> certain components (redirect to another component), or you can see a
> component, but with less privileges (e.g. view but not edit). In other
> words, how would you deal with CRUD (create, read, update, delete)
> role-based authorization on a component level?

I'd say it's up to the component. I've just added two new components
in tapestry5-acegi, called IfLoggedIn and IfRole, which can be used in
components such as:

<t:security.ifloggedin>
	You are logged in, welcome!
	<t:security.ifrole role="ROLE_ADMIN">
		You are even logged as admin, cool!
		<t:parameter name="else">
			Sorry, you don't have admin credentials.
		</t:parameter>
	</t:security.ifrole>
	<a t:type="actionlink" t:id="logout">Logout</a>
	<t:parameter name="else">
		Not logged in, please <t:pagelink t:page="LoginPage">do</t:pagelink>.
	</t:parameter>
</t:security.ifloggedin>

-- 
        regards,
        Robin

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: [T5] Restricting Page Access

Posted by Erik Vullings <er...@gmail.com>.
Hi,

Just wondering - when dealing with page authorizations, does this model
expand to component authorizations, i.e. you may visit the page, but not
certain components (redirect to another component), or you can see a
component, but with less privileges (e.g. view but not edit). In other
words, how would you deal with CRUD (create, read, update, delete)
role-based authorization on a component level?

Cheers
Erik

On 8/27/07, Robin Helgelin <lo...@gmail.com> wrote:
>
> On 8/26/07, Charles Mason <ch...@gmail.com> wrote:
> > I have made my own worker class, annotation and service. I understand
> > the acegi worker class except for the transform page part. I can't
> > work out how its managing to change the page. Its clearly modifying a
> > method but, I cant really work out how.
>
> It's the method transformPage() that actually changes the page. It's
> that last call to extendMethod(), that actually adds the call to the
> class. It attaches the class begin render and cleanup render. Acegi
> double checks things in cleanup whereas you might not need the extra
> fields injected earlier in that method.
>
> > The other thing I was struggling with is, how I actually integrate the
> > worker in to my service. I have a RequestFilter working from AppModule
> > which is executed for every request. But how do I use the worker class
> > I have just created? I could just call the transform method, but where
> > do I get the ClassTransformation object from. I assume there is some
> > correct way to apply a ComponentClassTransformWorker to a component>
>
> Yes, just contribute to the class transform worker, like this, and
> Tapestry will take care of running it on your classes.
> public static void contributeComponentClassTransformWorker(
>         OrderedConfiguration<ComponentClassTransformWorker>
> configuration, SecurityChecker securityChecker) {
>     configuration.add("Acegi", new AcegiWorker(securityChecker));
> }
>
> --
>         regards,
>         Robin
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>

Re: [T5] Restricting Page Access

Posted by Robin Helgelin <lo...@gmail.com>.
On 8/26/07, Charles Mason <ch...@gmail.com> wrote:
> I have made my own worker class, annotation and service. I understand
> the acegi worker class except for the transform page part. I can't
> work out how its managing to change the page. Its clearly modifying a
> method but, I cant really work out how.

It's the method transformPage() that actually changes the page. It's
that last call to extendMethod(), that actually adds the call to the
class. It attaches the class begin render and cleanup render. Acegi
double checks things in cleanup whereas you might not need the extra
fields injected earlier in that method.

> The other thing I was struggling with is, how I actually integrate the
> worker in to my service. I have a RequestFilter working from AppModule
> which is executed for every request. But how do I use the worker class
> I have just created? I could just call the transform method, but where
> do I get the ClassTransformation object from. I assume there is some
> correct way to apply a ComponentClassTransformWorker to a component>

Yes, just contribute to the class transform worker, like this, and
Tapestry will take care of running it on your classes.
public static void contributeComponentClassTransformWorker(
        OrderedConfiguration<ComponentClassTransformWorker>
configuration, SecurityChecker securityChecker) {
    configuration.add("Acegi", new AcegiWorker(securityChecker));
}

-- 
        regards,
        Robin

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: [T5] Restricting Page Access

Posted by Charles Mason <ch...@gmail.com>.
On 8/24/07, Robin Helgelin <lo...@gmail.com> wrote:>
> To ask your second question, the code tapestry5-acegi uses to wrap
> around the class is found here in this service:
> <http://www.localhost.nu/svn/public/tapestry5-acegi/trunk/src/main/java/nu/localhost/tapestry/acegi/services/internal/AcegiWorker.java>

Thanks for the info. I had been studying the code for a while. I
didn't look at that class much because I assumed from its title it was
dealing with the acegi library work rather than the tapestry side of
things. I should have known better than to assume things from class
names :)

What I want to do is have a SecuredPage annotation, which can be added
to any page class. Then before any page annotated with SecuredPage is
run, it calls a method that decides wither or not to redirect the user
to another page, bassed on there login info from the Application
State.

I have made my own worker class, annotation and service. I understand
the acegi worker class except for the transform page part. I can't
work out how its managing to change the page. Its clearly modifying a
method but, I cant really work out how.

The other thing I was struggling with is, how I actually integrate the
worker in to my service. I have a RequestFilter working from AppModule
which is executed for every request. But how do I use the worker class
I have just created? I could just call the transform method, but where
do I get the ClassTransformation object from. I assume there is some
correct way to apply a ComponentClassTransformWorker to a component>

Any help / suggestions would be really appreciated.

Charlie M

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: [T5] Restricting Page Access

Posted by Robin Helgelin <lo...@gmail.com>.
On 8/24/07, Charles Mason <ch...@gmail.com> wrote:
> @Secured("ROLE_ADMIN")
> public class AdminPage
> {
> }
>
> I was wondering how this worked. I am assuming its through some sort
> of T5 service. I was looking at the documentation on the T5 site,
> although I can't figure how to do something like that. I also had a
> look at the Tapestry 5 acegi library. But not knowing acegi, its hard
> to see how this works in the source.
>
> I was wondering if someone could tell me the basic principle of what I
> need to write or implement to be able to hook in the to the page
> loading procedure  from just an annotation.

The tapestry5-acegi library adds a few request filters that run
between your browser and the T5 engine. It also adds a few hooks to
your classes defined by the @Secured annotation. These hooks are
executed before your class by a few Acegi classes which checks right
permissions/roles, etc and either gives you access to the page or
redirects you to the defined login page.

Depending on your needs, Acegi might be the bigger hammer to punch the
little nail :-).

To ask your second question, the code tapestry5-acegi uses to wrap
around the class is found here in this service:
<http://www.localhost.nu/svn/public/tapestry5-acegi/trunk/src/main/java/nu/localhost/tapestry/acegi/services/internal/AcegiWorker.java>

-- 
        regards,
        Robin

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org