This particular example wouldn't work as things stand today - the
filters are executed in the order in which they are defined, so the
roles filter would execute and redirect to an unauthorized url before
the 'unauthorizedUrl' filter has its chance to execute.

However, any filter extending from PathMatchingFilter (which includes
all of Shiro's pre-defined authc/authz filters) support per-path
configuration already, so you could do something like this:

/premium/** = myFilter, myRoles[paid, unauthorizedUrl=/upgrade.jspa],
anotherFilter, ...

Where you subclass the existing RolesAuthorizationFilter (to create
the 'myRoles' instance's class) and override the
AccessControlFilter#onAccessDenied(request, response, mappedValue)
method.  There you can look at the mappedValue (which is a String[]),
see if one of those strings is your unauthorizedUrl=blah string.  If
so, you call  WebUtils.issueRedirect(request, response,
unauthorizedUrl);

Another approach is to have an 'unauthorizedUrl' filter that sits in
the front of the chain, and all it does is set a request attribute
indicating the overridden url.  Then the
AuthorizationFilter#onAccessDenied method could be refactored to look
for that request attribute, and if it exists, then use it.  If it
doesn't exist, then fall back to its internal 'unauthorizedUrl'
property.

I think I prefer the former rather than the latter because it feels
more natural from a configuration standpoint (i.e. I only want to
'tell' the role filter to use this particular url - not the whole
chain).  But there is no reason why both approaches can't exist - I
can see use cases where you would actually want to override a property
for the whole chain and not just a single filter in the chain.

HTH!

-- 
Les Hazlewood
Founder, Katasoft, Inc.
Application Security Products & Professional Apache Shiro Support and Training:
http://www.katasoft.com

On Sun, Nov 14, 2010 at 10:33 AM, Alan D. Cabrera <[email protected]> wrote:
> Sometimes I want an area for those who have paid for a premium service, they 
> would have a role paid.  Other areas are for if a user has been 
> authenticated.  When unpaid users wander into the premium area it would be 
> nice if they would be redirected to another page enticing them to upgrade 
> their membership.
>
> I envision something like:
>
>    <bean id="shiroFilter" 
> class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
>        <property name="securityManager" ref="securityManager"/>
>        <property name="loginUrl" value="/signin/signIn.jspa?first=true"/>
>        <property name="successUrl" value="/home.jsp"/>
>        <property name="unauthorizedUrl" value="/unauthorized.jsap"/>
>        <property name="filterChainDefinitions">
>            <value>
>                /signin/** = myFilter
>                /admin/** = myFilter, roles[admin]
>                /premium/** = myFilter, roles[paid], 
> unauthorizedUrl[/upgrade.jspa]
>            </value>
>        </property>
>    </bean>
>
> Thoughts?
>
>
> Regards,
> Alan

Reply via email to