views:

377

answers:

4

Hi,

I'm currently developing a menu for my application that should be able to display only the controllers that the current user can access (requestmap defined in the database).

How can I check if the current user has access to a specific controller and action?

Thanks, Jan

A: 

You have to configure the file config/SecurityConfig.groovy (if it does not exists, create it, this overrides the default Security Configuration)

Add this entry:

requestMapString = """\
            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
            PATTERN_TYPE_APACHE_ANT
            /=IS_AUTHENTICATED_REMEMBERED
            /login/auth=IS_AUTHENTICATED_ANONYMOUSLY
            /login/authajax=IS_AUTHENTICATED_ANONYMOUSLY
            /login/authfail=IS_AUTHENTICATED_ANONYMOUSLY 
            /js/**=IS_AUTHENTICATED_ANONYMOUSLY
            /css/**=IS_AUTHENTICATED_ANONYMOUSLY
            /images/**=IS_AUTHENTICATED_ANONYMOUSLY
            /plugins/**=IS_AUTHENTICATED_ANONYMOUSLY
            /**=IS_AUTHENTICATED_REMEMBERED
          """

This is means that you have to log in to enter the site. But all the resources (css, js, images, etc) is accessed without authentification.

If you want specific role only enter specific controller: For example, for UserController:

    /user/**=ROLE_ADMIN
    /role/**=ROLE_ADMIN 

For more information: http://www.grails.org/AcegiSecurity+Plugin+-+Securing+URLs

Regards

nahn
Sorry if my question was misunderstanding, I have already secured my controllers with a RequestMap (not in the SecurityConfig.groovy, but using a database table) and all this works perfect.My question was, how can I check if the current user has access to a certain controller and action.I'm thinking of it like this: if (currentUserHasAccess(controller, action)) { do_some_stuff }
Jan
A: 

When dealing with permissions in views and taglibs, you can use the AuthorizeTagLib that's provided by the plugin.

For example, if you don't want a menu item to appear in your list for unauthenticated users, you might use:

<g:isLoggedIn>
  <li>Restricted Link</li>
</g:isLoggedIn>

If you have more specific roles defined and those roles are tied to your controller/action request mapping, you can use other tags, such as:

<g:ifAllGranted role="ROLE_ADMINISTRATOR">
  <li>Administrator Link</li>
</g:ifAllGranted>

In my experience, there's not yet a good way to tie the request mapping to your markup - I think you're going to have to use some of the above tags to limit access to content within a particular GSP.

I think that Burt Beckwith has a future modification (and is currently providing a beta version) to the plugin that integrates some ACL stuff that might solve this problem better in the future, but for now, I think the best approach is a hybrid request map + GSP tags one.

Rob Hruska
I've seen that TagLib, but it doesn't really solve my problem.Maybe I could use the ifAllGranted or ifAnyGranted methods, if there is a way to match a controller and action to an entry in my RequestMap... Does anyone know how this is done?
Jan
A: 

As far as I can tell, there doesn't look like there's an easy way to do it.

You can inject an instance of the grails AuthenticatedVetoableDecisionManager which is a concrete class of spring's AbstractAccessDecisionManager by doing this:

def accessDecisionManager

This has a "decide" method on it that takes 3 parameters

decide(Authentication authentication, Object object, ConfigAttributeDefinition config)

This is probably the method that you'd need to call and pass in the right things to figure out if the user with the auth creds can access that "object" (which looks like it's normally a request/response). Some additional digging around might prove out something workable here.

Short term, it's probably easier to use the ifAnyGranted taglib as another poster mentions.

Ted Naleid
Thanks man, I'll look for a solution in this direction. Anyway, I'd like to use the ifAnyGranted taglib, but then I still need to figure out which roles apply in the current case, that means, finding a way to get the roles for a specific controller/action out of my RequestMap.
Jan
A: 

I'm not sure about in Groovy, but in Java (so I assume Groovy too...) you could do (minus NPE checks):

GrantedAuthority[] authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
boolean isAdmin = false;
for(GrantedAuthority authority : authorities) {
    String role = authority.getAuthority();
    if(role != null && role.equals("ROLE_ADMIN")) {
        isAdmin = true;
        break;
    }
}

As for knowing whether or not the action is supported, you'd have to call the RequestMap service to get the roles for the mapping and see if it contains the found user role.

Droo
Thanks for your code, but I think this is what ifAnyGranted does... The interesting Part ist this "RequestMap Service" -- do you have more information about it? I couldn't find anything with google...
Jan