You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shiro.apache.org by "Alan D. Cabrera" <li...@toolazydogs.com> on 2011/06/26 17:01:38 UTC

Unauthorized URL for different entries in filter chain

I think I mentioned this a while back and I've run into this again recently.  I would love to have different unauthorizedUrl entries per chain

        <property name="filterChainDefinitions">
            <value>
                /admin/** = myFilter, roles[admin], /service/notadmin.jsp
                /work/** = myFilter, roles[verified], /service/notverified.jsp
                /owners/** = myFilter, roles[owner], /service/notowner.jsp
                /account/** = myFilter
            </value>
        </property>

I'm going to make a branch to show my proposed changes and if everyone is happy with them I'll move them into trunk.  The changes will be backward compatible.


Regards,
Alan


Re: Unauthorized URL for different entries in filter chain

Posted by Les Hazlewood <lh...@apache.org>.
I was only opposed to this idea for filters because that's an
unexpected behavior for most applications (multiple instances of the
same filter class) and doesn't sound too intuitive for those
accustomed to the traditional servlet model.  If we dump the Filter
approach (and have our own similar API concept for example), I think I
could get on board for that.

I can't remember off of the top of my head how easy it would be to do
what you've proposed INI config Kalle.  If it was super easy for
end-users, I'd definitely be open to that idea.

But on a side note, I don't think setting request attributes is a bad
thing or even orthogonal to the mutliple-filter-instances approach -
it allows filters to 'talk' to each other in an unobtrusive way
without requiring subclassing.  Maybe this isn't needed at all with
the multiple-filter-instance approach, but I haven't thought about if
it'd be useful or not in that case.

I'm gonna open another discussion thread about how we might be able to
support the multiple-filter-instance approach cleanly and intuitively
while still retaining backwards compatibility.

Best,

Les

Re: Unauthorized URL for different entries in filter chain

Posted by Kalle Korhonen <ka...@gmail.com>.
For 2.0, the third approach would be to have each multiples instances
of the same filter, each carrying its own configuration. That way, you
wouldn't constantly need to write and read request attributes. It'd
would simplify things and allow more flexibility (disabling specific
filter instances etc.). We had a long discussion on that with Les in a
different thread, but so far he was opposing the idea. I've
implemented the concept for the purposes of tapestry-security module
(http://tynamo.org/tapestry-security+guide).

Kalle


On Sun, Jun 26, 2011 at 12:14 PM, Les Hazlewood <lh...@apache.org> wrote:
> Hi Alan,
>
> Yep, that's one of two ways I can see this working (although I'd
> probably represent the string a bit differently - see below).
>
> Approach #1:
>
> Have url configurable on a per-request (e.g. per path) basis like
> you've shown, available to any of the AuthorizationFilter subclasses.
>
> I'd probably represent this as a named key/value pair in the config
> string, e.g.:
>
> /whatever/** = someFilter, roles[admin, unauthzUrl=/service/notadmin.jsp]
>
> This way the string is a bit more specific and allows any configurable
> property to be configured no matter the order it is written.  A little
> nicer so people don't need to remember a particular string format or
> potentially leave empty spaces if other fields are introduced in the
> future (e.g. admin||somethingElse)
>
> I believe this approximates more of what the 2.0 codebase will probably be like.
>
> Approach #2:
>
> Have a filter that configures the URL as a request attribute so any
> filter in the chain can react to it as needed.
>
> This is my preferred approach and is definitely how the newer filters
> (and whatever mechanism we choose for 2.0) will probably work.  This
> technique is what will allow end-users to not have to subclass Shiro
> Filter classes so much since they can inspect the request in whatever
> way they wish.
>
> For example:
>
> /whatever/** = unauthzUrl[/service/notadmin.jsp], someFilter, roles[admin]
>
> The 'unauthzUrl' filter will place the configured URL in the request
> as an attribute (request.setAttribute) using a well-known key.  Then,
> any AuthorizingFilter subclass (roles, ssl, perms, etc) can lookup
> that attribute if it exists.  If it exists, they redirect using that
> url.  If it doesn't exist, then they fallback to their
> 'unauthorizedUrl' property.
>
> I believe both approaches should be supported, but I prefer the 2nd
> approach due to how clean it feels to me - it feels more like a
> 'mixin' which is much more flexible than subclassing (which we'd like
> to move away from as we've discussed).  It is definitely backwards
> compatible too (new support would be added, but existing functionality
> wouldn't be lost).
>
> Thoughts?
>
> Cheers,
>
> --
> Les Hazlewood
> CTO, Katasoft | http://www.katasoft.com | 888.391.5282
> twitter: http://twitter.com/lhazlewood
> katasoft blog: http://www.katasoft.com/blogs/lhazlewood
> personal blog: http://leshazlewood.com
>
>
> On Sun, Jun 26, 2011 at 11:47 AM, Alan D. Cabrera <li...@toolazydogs.com> wrote:
>
>> Looking at the code I'm wondering if I shouldn't extend the particular filter to do something like this.
>>
>>       <property name="filterChainDefinitions">
>>           <value>
>>               /admin/** = myFilter, myRoles[admin|/service/notadmin.jsp]
>>               /work/** = myFilter, myRoles[verified|/service/notverified.jsp]
>>               /owners/** = myFilter, myRoles[owner|/service/notowner.jsp]
>>               /account/** = myFilter
>>           </value>
>>       </property>
>>
>> No code changes needed then.
>>
>>
>> Regards,
>> Alan
>

Re: Unauthorized URL for different entries in filter chain

Posted by "Alan D. Cabrera" <li...@toolazydogs.com>.
I like approach #1 and don't care so much for #2.  :)  Creating a filter just so that you could set a property in other filters seems a bit awkward; it's not a mixin, imo, since all the participating filters have to be prepared to collaborate ahead of time.  

/whatever/** = someFilter, roles[admin, unauthzUrl=/service/notadmin.jsp]

How would this work from a filter's perspective?  We can keep a single instance of a filter around and it handles all requests or we can create a new instance of the filter per call.  The former would be backward compatible so I'll discuss that first.

When set of filters match a path, a set of the filters's methods are called by the framework.  This allows the filters to participate in the framework's processing of the client's request.  Let's say that these methods are foo and bar.  The methods foo and bar have a set of required arguments; these would be the arguments that Shiro 1.1 has.  But some filters could have additional parameters and we map the key/value pairs in the filter chain config to those parameters.  For the roles filter foo could be:

foo(ServletRequest request, ServletResponse response, String mappedValue, String unauthzUrl)

for the someFilter it would be:

foo(ServletRequest request, ServletResponse response)

where the last signature would have a default do-nothimg implementation.  The only problem with this is that the current implementation extensively uses class inheritance to extend/override features and it's not clear to me that we have a concise set of "event" methods between the framework and filters; the events seem to be buried inside abstract classes.

The other way is for if we create the filter per request; something we are apparently thinking for 2.0.  When we create that instance set we set it's bean properties from the key/value pairs in the filter chain config.

Thoughts?


Regards,
Alan

On Jun 26, 2011, at 12:14 PM, Les Hazlewood wrote:

> Hi Alan,
> 
> Yep, that's one of two ways I can see this working (although I'd
> probably represent the string a bit differently - see below).
> 
> Approach #1:
> 
> Have url configurable on a per-request (e.g. per path) basis like
> you've shown, available to any of the AuthorizationFilter subclasses.
> 
> I'd probably represent this as a named key/value pair in the config
> string, e.g.:
> 
> /whatever/** = someFilter, roles[admin, unauthzUrl=/service/notadmin.jsp]
> 
> This way the string is a bit more specific and allows any configurable
> property to be configured no matter the order it is written.  A little
> nicer so people don't need to remember a particular string format or
> potentially leave empty spaces if other fields are introduced in the
> future (e.g. admin||somethingElse)
> 
> I believe this approximates more of what the 2.0 codebase will probably be like.
> 
> Approach #2:
> 
> Have a filter that configures the URL as a request attribute so any
> filter in the chain can react to it as needed.
> 
> This is my preferred approach and is definitely how the newer filters
> (and whatever mechanism we choose for 2.0) will probably work.  This
> technique is what will allow end-users to not have to subclass Shiro
> Filter classes so much since they can inspect the request in whatever
> way they wish.
> 
> For example:
> 
> /whatever/** = unauthzUrl[/service/notadmin.jsp], someFilter, roles[admin]
> 
> The 'unauthzUrl' filter will place the configured URL in the request
> as an attribute (request.setAttribute) using a well-known key.  Then,
> any AuthorizingFilter subclass (roles, ssl, perms, etc) can lookup
> that attribute if it exists.  If it exists, they redirect using that
> url.  If it doesn't exist, then they fallback to their
> 'unauthorizedUrl' property.
> 
> I believe both approaches should be supported, but I prefer the 2nd
> approach due to how clean it feels to me - it feels more like a
> 'mixin' which is much more flexible than subclassing (which we'd like
> to move away from as we've discussed).  It is definitely backwards
> compatible too (new support would be added, but existing functionality
> wouldn't be lost).
> 
> Thoughts?
> 
> Cheers,
> 
> -- 
> Les Hazlewood
> CTO, Katasoft | http://www.katasoft.com | 888.391.5282
> twitter: http://twitter.com/lhazlewood
> katasoft blog: http://www.katasoft.com/blogs/lhazlewood
> personal blog: http://leshazlewood.com
> 
> 
> On Sun, Jun 26, 2011 at 11:47 AM, Alan D. Cabrera <li...@toolazydogs.com> wrote:
> 
>> Looking at the code I'm wondering if I shouldn't extend the particular filter to do something like this.
>> 
>>       <property name="filterChainDefinitions">
>>           <value>
>>               /admin/** = myFilter, myRoles[admin|/service/notadmin.jsp]
>>               /work/** = myFilter, myRoles[verified|/service/notverified.jsp]
>>               /owners/** = myFilter, myRoles[owner|/service/notowner.jsp]
>>               /account/** = myFilter
>>           </value>
>>       </property>
>> 
>> No code changes needed then.
>> 
>> 
>> Regards,
>> Alan


Re: Unauthorized URL for different entries in filter chain

Posted by Les Hazlewood <lh...@apache.org>.
Hi Alan,

Yep, that's one of two ways I can see this working (although I'd
probably represent the string a bit differently - see below).

Approach #1:

Have url configurable on a per-request (e.g. per path) basis like
you've shown, available to any of the AuthorizationFilter subclasses.

I'd probably represent this as a named key/value pair in the config
string, e.g.:

/whatever/** = someFilter, roles[admin, unauthzUrl=/service/notadmin.jsp]

This way the string is a bit more specific and allows any configurable
property to be configured no matter the order it is written.  A little
nicer so people don't need to remember a particular string format or
potentially leave empty spaces if other fields are introduced in the
future (e.g. admin||somethingElse)

I believe this approximates more of what the 2.0 codebase will probably be like.

Approach #2:

Have a filter that configures the URL as a request attribute so any
filter in the chain can react to it as needed.

This is my preferred approach and is definitely how the newer filters
(and whatever mechanism we choose for 2.0) will probably work.  This
technique is what will allow end-users to not have to subclass Shiro
Filter classes so much since they can inspect the request in whatever
way they wish.

For example:

/whatever/** = unauthzUrl[/service/notadmin.jsp], someFilter, roles[admin]

The 'unauthzUrl' filter will place the configured URL in the request
as an attribute (request.setAttribute) using a well-known key.  Then,
any AuthorizingFilter subclass (roles, ssl, perms, etc) can lookup
that attribute if it exists.  If it exists, they redirect using that
url.  If it doesn't exist, then they fallback to their
'unauthorizedUrl' property.

I believe both approaches should be supported, but I prefer the 2nd
approach due to how clean it feels to me - it feels more like a
'mixin' which is much more flexible than subclassing (which we'd like
to move away from as we've discussed).  It is definitely backwards
compatible too (new support would be added, but existing functionality
wouldn't be lost).

Thoughts?

Cheers,

-- 
Les Hazlewood
CTO, Katasoft | http://www.katasoft.com | 888.391.5282
twitter: http://twitter.com/lhazlewood
katasoft blog: http://www.katasoft.com/blogs/lhazlewood
personal blog: http://leshazlewood.com


On Sun, Jun 26, 2011 at 11:47 AM, Alan D. Cabrera <li...@toolazydogs.com> wrote:

> Looking at the code I'm wondering if I shouldn't extend the particular filter to do something like this.
>
>       <property name="filterChainDefinitions">
>           <value>
>               /admin/** = myFilter, myRoles[admin|/service/notadmin.jsp]
>               /work/** = myFilter, myRoles[verified|/service/notverified.jsp]
>               /owners/** = myFilter, myRoles[owner|/service/notowner.jsp]
>               /account/** = myFilter
>           </value>
>       </property>
>
> No code changes needed then.
>
>
> Regards,
> Alan

Re: Unauthorized URL for different entries in filter chain

Posted by "Alan D. Cabrera" <li...@toolazydogs.com>.
On Jun 26, 2011, at 8:01 AM, Alan D. Cabrera wrote:

> I think I mentioned this a while back and I've run into this again recently.  I would love to have different unauthorizedUrl entries per chain
> 
>        <property name="filterChainDefinitions">
>            <value>
>                /admin/** = myFilter, roles[admin], /service/notadmin.jsp
>                /work/** = myFilter, roles[verified], /service/notverified.jsp
>                /owners/** = myFilter, roles[owner], /service/notowner.jsp
>                /account/** = myFilter
>            </value>
>        </property>
> 
> I'm going to make a branch to show my proposed changes and if everyone is happy with them I'll move them into trunk.  The changes will be backward compatible.

Looking at the code I'm wondering if I shouldn't extend the particular filter to do something like this.

       <property name="filterChainDefinitions">
           <value>
               /admin/** = myFilter, myRoles[admin|/service/notadmin.jsp] 
               /work/** = myFilter, myRoles[verified|/service/notverified.jsp] 
               /owners/** = myFilter, myRoles[owner|/service/notowner.jsp]
               /account/** = myFilter
           </value>
       </property>

No code changes needed then.


Regards,
Alan