You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by JMalkan <JM...@mail.com> on 2011/03/12 02:51:48 UTC

What is the recommended way for Attribute Authorizaton

Hi,

So far I have implemented Authorization up to Instance level following the
http://shiro.apache.org/java-authorization-guide.html.

I am using Guice as DI (Dependency Injection) and Jersey for Rest service.
Authentication and Authorization happens before client request hits any web
service on the server.

In my realm's doGetAuthorizationInfo method I read permissions from
database. which looks something like user:read.

where "user" is the base resource path defined for Jersy User WebService.

I also extended HttpMethodPermissionFilter to provide custom behavior
because We keep adding resources and found it easy to manage without change
to shiro.ini file.

Here is the customization: It would have been nice if this was built in and
allowed to over-write from shiro.ini


  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isAccessAllowed(ServletRequest request, ServletResponse
response, Object mappedValue) throws IOException
  {
    String service;
    String requestURI = ((HttpServletRequest) request).getRequestURI();
    int startIndx = "/nb/service/".length();
    int finishIndx = requestURI.indexOf('/', startIndx);
    
    if (finishIndx == -1)
      service = requestURI.substring(startIndx);
    else
      service = requestURI.substring(startIndx, finishIndx);
    
    String[] perms = new String[] {service};
    logger.debug("service={}, perms={}, mappedValue={}, RequestURI={}", new
Object[] {service, perms, mappedValue, requestURI});
    
    return super.isAccessAllowed(request, response, perms);
  }



So far so good. Now I want to take this to the next level. So I am thinking
of following changes
1. Modify permissions read by doGetAuthorizationInfo so it looks something
like user:update:1,5,9 user:read:5,6,7 userAddress:update:3,4,5
2. Modify my custom permission filter class which extends
HttpMethodPermissionFilter and over-write 
  protected String getHttpMethodAction(ServletRequest request) to return
read:id reading from request object.

I am hoping there is a better/easier way.


I also a few more complexities.

1. I need to apply permission based on sub-attribute which is something
like.
    subject from to role "admin" can edit "user" published address.
    subject from role "manager" can edit "user" non-published addresses.
2. "user" address may be published any time and i need to apply this
permission dynamically. So caching permission may cause problems. May be
cache could be blown away based on some event.
3. My application can also query "user" resource like user?gender=male which
queries database and returns all the records matching gender= male. What is
the best way to filter these results match subjects permission. If subject
has read permission on id 3,5,7 but not all.
One way to handle this is to return all the results from database and client
filter out but that doesn't work if records are paginated and database is
returning one page at a time.
Other possibility is to filter this out on the database.

The more I think I feel like Shiro does most of the things. So far I have
tried to keep security code out in filter and realm but I might have to make
server/database somewhat aware of authorization. Just a matter of finding
out the right place.


Any help is appreciated.


Jiggy.

--
View this message in context: http://shiro-user.582556.n2.nabble.com/What-is-the-recommended-way-for-Attribute-Authorizaton-tp6163525p6163525.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: What is the recommended way for Attribute Authorizaton

Posted by Brian Demers <br...@gmail.com>.
Not sure if this helps exactly, but we have a similar use case.

We have a class ShiroSecurityFilter that extends IniShiroFilter

In the configure method we do the following:

        FilterChainManager filterChainManager =
            ( (PathMatchingFilterChainResolver)
super.getFilterChainResolver() ).getFilterChainManager();

        ProtectedPathManager protectedPathManager =
this.getPlexusContainer().lookup( ProtectedPathManager.class );
        // this cannot be injected as long as the configuration comes
from the servlet config.
        // TODO: push the ini config in its own file.
        if ( FilterChainManagerAware.class.isInstance( protectedPathManager ) )
        {
            ( (FilterChainManagerAware) protectedPathManager
).setFilterChainManager( filterChainManager );
        }

And basically:

public interface ProtectedPathManager
{
    /**
     * Adds a protected resource for the <codepathPattern</code>, and
configures it with the<code>filterExpression</code>.
     * @param pathPattern the pattern of the path to protect (i.e. ant pattern)
     * @param filterExpression the configuration used for the filter
protecting this pattern.
     */
    public void addProtectedResource( String pathPattern, String
filterExpression );
}

(these are some of the bits I want to replace with proper DI

This allows us to add resources on the fly,  which is a bit different
then what you need to do, but this is how we extend from the INI
configuration.


On Fri, Mar 11, 2011 at 8:51 PM, JMalkan <JM...@mail.com> wrote:
> Hi,
>
> So far I have implemented Authorization up to Instance level following the
> http://shiro.apache.org/java-authorization-guide.html.
>
> I am using Guice as DI (Dependency Injection) and Jersey for Rest service.
> Authentication and Authorization happens before client request hits any web
> service on the server.
>
> In my realm's doGetAuthorizationInfo method I read permissions from
> database. which looks something like user:read.
>
> where "user" is the base resource path defined for Jersy User WebService.
>
> I also extended HttpMethodPermissionFilter to provide custom behavior
> because We keep adding resources and found it easy to manage without change
> to shiro.ini file.
>
> Here is the customization: It would have been nice if this was built in and
> allowed to over-write from shiro.ini
>
>
>  /**
>   * {@inheritDoc}
>   */
>  @Override
>  public boolean isAccessAllowed(ServletRequest request, ServletResponse
> response, Object mappedValue) throws IOException
>  {
>    String service;
>    String requestURI = ((HttpServletRequest) request).getRequestURI();
>    int startIndx = "/nb/service/".length();
>    int finishIndx = requestURI.indexOf('/', startIndx);
>
>    if (finishIndx == -1)
>      service = requestURI.substring(startIndx);
>    else
>      service = requestURI.substring(startIndx, finishIndx);
>
>    String[] perms = new String[] {service};
>    logger.debug("service={}, perms={}, mappedValue={}, RequestURI={}", new
> Object[] {service, perms, mappedValue, requestURI});
>
>    return super.isAccessAllowed(request, response, perms);
>  }
>
>
>
> So far so good. Now I want to take this to the next level. So I am thinking
> of following changes
> 1. Modify permissions read by doGetAuthorizationInfo so it looks something
> like user:update:1,5,9 user:read:5,6,7 userAddress:update:3,4,5
> 2. Modify my custom permission filter class which extends
> HttpMethodPermissionFilter and over-write
>  protected String getHttpMethodAction(ServletRequest request) to return
> read:id reading from request object.
>
> I am hoping there is a better/easier way.
>
>
> I also a few more complexities.
>
> 1. I need to apply permission based on sub-attribute which is something
> like.
>    subject from to role "admin" can edit "user" published address.
>    subject from role "manager" can edit "user" non-published addresses.
> 2. "user" address may be published any time and i need to apply this
> permission dynamically. So caching permission may cause problems. May be
> cache could be blown away based on some event.
> 3. My application can also query "user" resource like user?gender=male which
> queries database and returns all the records matching gender= male. What is
> the best way to filter these results match subjects permission. If subject
> has read permission on id 3,5,7 but not all.
> One way to handle this is to return all the results from database and client
> filter out but that doesn't work if records are paginated and database is
> returning one page at a time.
> Other possibility is to filter this out on the database.
>
> The more I think I feel like Shiro does most of the things. So far I have
> tried to keep security code out in filter and realm but I might have to make
> server/database somewhat aware of authorization. Just a matter of finding
> out the right place.
>
>
> Any help is appreciated.
>
>
> Jiggy.
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/What-is-the-recommended-way-for-Attribute-Authorizaton-tp6163525p6163525.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>