Access/check Spring Security hierarchical roles programmatically - grails

In my Grails project I defined multiple hierarchical roles using the Spring Security plugin e.g. ROLE_USER > SOME_OTHER_ROLE. When securing controller methods using the #Secured annotation it works just fine. However, I also would like to check the role programmatically in my code for one use case. Using the following approach I always get a false even though the user inherits the role through hierarchical role definition:
request.isUserInRole('SOME_OTHER_ROLE')
Also the following calls never directly return the inherited roles:
SecurityContextHolder.context?.authentication?.authorities
springSecurityService.getPrincipal().getAuthorities()
Is there a way of checking if the user also has the inherited role?

This seems like a bug (or at least an omission) in SecurityContextHolderAwareRequestWrapper which adds a request wrapper to implement the isUserInRole method.
You can use the roleVoter bean's extractAuthorities method. Add a dependency injection for it (def roleVoter) and then call
def allRoles = roleVoter.extractAuthorities(
SecurityContextHolder.context.authentication)

Related

Including Domain Object Security #PostFilter in Spring Data repositories Pageable endpoints

In my project I use Spring-Data, Spring-Data-Rest and Spring-Security.
What I need to accomplish is to implement domain object security (ACL) over these repositories. Specificaly #PostFilter over Pageable.findAll() method.
Method level security is easily implemented as outlined here.
There is also a section in docs about using security expression with #Query here.
But although I can use hasPermission(..) method inside #Query too, there is no way to include the object (SQL row) in this method - to be specific do this:
#Query("select u from #{#entityName} u where 1 = ?#{security.hasPermission(u, 'read') ? 1 : 0}")
Now I understand that this is way different than modifying the query pre-execution like this:
#Query("select m from Message m where m.to.id = ?#{ principal?.id }")
I also found the following jira issue:
https://jira.spring.io/browse/DATACMNS-293
Which I suspect that once it gets resolved there will be a solution to this, but it doesn't seem like it's going to be anytime soon.
I still need to implement this functionality and for that I would like to get your input and pointers on possible solutions.
Right now I am thinking about creating my custom annotation that will mimmick the #PostFilter one and use the same syntax but will get invoked manually inside my own BaseRepositoryImplementation. There I will get the repository interface from type and Repositories#getRepositoryInformationFor(type)#getRepositoryInterface(), find the annotation on respective method and manually invoke the security check.
Do you maybe have a different solution, or some notes about my proposed solution?
Also do you happen to know if there is any timetable on the mentioned jira issue?
One lightweight way is to do it is using the hasPermission() method and implementing your own "Permission Evaluator" at the Controller level, if that's an option for you.
#PreAuthorize("hasPermission(#employee, 'edit')")
public void editEmployee(Employee employee) {
...
}
#Component
public class PermissionEvaluatorImpl implements PermissionEvaluator {
#Override
public boolean hasPermission(Authentication auth,
Object targetDomainObject, Object permission) {
// return true if "auth" has "permission" permission for the user.
// Current-user can be obtained from auth.
}
...
}
This is described in more detail here: http://www.naturalprogrammer.com/spring-domain-object-security-logged-in-user/

Custom roles architecture in ASP.NET MVC 5, Dependency Injection issues

I've got an architecture issue that I'm hoping someone can be of assistance to guide me in a more ideal strategy. The way I've been forced to do this reeks of "code smell".
I've got two different kinds of "Roles". I've got the built in Identity Roles, and I've got a custom set of roles (User Group Roles). I store these User Group Roles in a database, essentially a relationship between a user id, a usergroup role id, and a usergroup id. I'm using Ninject for dependency injection of my UserGroupService that handles all the CRUD operations of assigning users with certain usergroup roles to usergroups.
My first plan of attack was to create a custom authorization attribute that I could place on actions, similar to the Identity [Authorize(Role="")] attribute. I did not have any luck with this because I cannot inject a service into an attribute class (needs a parameterless constructor).
After that didn't work, my second plan of attack was to write an extension method for IPrincipal, essentially mimicking User.IsInRole("") with User.IsInUserGroupRole(""). This didn't work because I cannot inject a service into a static class.
Currently I am stuck including some booleans in the model of every view that has role based logic involved. So for instance:
public ActionResult Navigation()
{
var isSystemAdmin = User.IsInRole("Administrator");
var isUserGroupAdmin = _userGroupService.IsUserGroupAdmin(User.Identity.GetUserId()) && !isSystemAdmin;
var isGeneralUser = !isSystemAdmin && !isUserGroupAdmin;
var model = new NavigationViewModel
{
IsSystemAdmin = isSystemAdmin,
IsUserGroupAdmin = isUserGroupAdmin,
IsGeneralUser = isGeneralUser
};
return PartialView("_Navigation", model);
}
The issue here is that I have to do this any time I want to determine what kind of roles the user is currently in. It works, but it smells.
Am I missing something here? I think the most ideal option would be the extension method strategy of being able to call it right off of User, but cannot seem to make that work.
Constructor DI is not the only way to get access to a dependency.
Each IOC has a way of resolving a dependency, all you need is a reference to the IOC container. So, even if your attribute requires a parameterless constructor you could still resolve the dependency manually.
Something like this should help :
http://www.c-sharpcorner.com/UploadFile/47fc0a/resolving-dependency-using-ninject/
Is it a great way to use your IOC this way? Probably not but it sure beats what you're doing now.

Grails - #Transactional annotation on generating simple Controller

Grails newb here. I was using GGTS to generate a controller for a simple User model (string user, string passed)
On looking at the GGTS generated code, I noticed that there is #Transactional annotation on certain actions like delete(), save() and update().
My question is, why is #Transactional used in the controller and why is #Transactional not used in Services?
Newb in grails
In grails the correct way to do all DB related work and DB transactions is to do in service classes and not controllers. So by default controllers don't have privileges to do transaction and hence we use #Transactional annotation. While in services by default transaction is allowed.
If you use a service method which does some DB transaction then you need to make your controller action transactional by #Transactional annotation. While no need to mention it in service method.
Other way round if you donot make the controller transactional then you will need to mention it in service class.
Best practice will be not to use auto generated code as it will be less maintainable for a beginner. Official documentation will be your best help and while doing it when you will create controller you will not find any transactional annotation while when you will create service class you will see transactional annotation at the class level.
P.S. - 'Create' class is not equal to 'generate'.

Authorize roles via database

I am building an ASP.net MVC 4 application.
In the past I have used the [Authorize] attribute to authorize users according to their role(s).
However, I now need to a more flexible solution where role authorization can be changed by altering the database rather than changing the source code.
Can anyone recommend a suitable way to do this?
I have looked into overriding the OnAuthorize method but apparently this is not recommended due to issues with output caching.
You can do something like this, we have been using this in our application
[AttributeUsageAttribute
(AttributeTargets.Class | AttributeTargets.Struct |
AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
public class RequirePermissionsAttribute : ActionFilterAttribute, IAuthorizationFilter
{
// Use inbuilt methods
//OnAuthorization
//HandleUnauthorizedRequest
//OnCacheAuthorization
}
[RequirePermissions(PermissionItems.ViewThisPage)]
public ActionResult Index()
{
}
Not sure if I understood your requirement correctly, but you could have two levels of roles, with a data model something like:
User -in-> Role -has-> Permission
With m-n relationships between Users and Roles, and between Roles and Permissions.
If you do this, your permissions can be quite fine-grained and stable, while roles can be coarse-grained and flexibly mapped to sets of permissions.
One way to implement this is to simply write a custom RoleProvider that does the join Users-Roles-Permissions and returns the permissions as application roles.
If you do this, you can use the standard Authorize attribute, specifying one of your fine-grained permission names rather than a coarse-grained role name, e.g.:
[Authorize(Permissions.ViewCustomers)]

Checking whether the user authenticated using spring security inside a filter

I'm trying to do this in my groovy class which is in src directory of my grails application.
Its an Filter. The class looks like this :
class Proxy implements Filter {
}
Inside the init method I'm getting the springSecurityService bean using :
GrailsApplication application = org.codehaus.groovy.grails.commons.ApplicationHolder.getApplication()
springSecurityService = application.getMainContext().getBean("springSecurityService")
And inside my doFilter I'm trying to find whether the user is been authenticated or not. I tried:
springSecurityService.isLoggedIn()
but its always returning false.
Where I'm making the mistake?
Thanks in advance.
Is it possible the order of your filters are incorrect? Your custom Filter would need to be invoked after the Spring Security Filter. If you perform new Exception().printStackTrace() inside your filter, do you see the SecurityContextPersistenceFilter in the stack? If not, then you need to change your Filter (Proxy) to be after the springSecurityFilterChain.
Try to use SecurityContextHolder
SecurityContextHolder.getContext().getAuthentication()
(but this is Java; I'm sure there is something similar you can find)

Resources