I am using spring security annotations in my project. There are scenarios when i want to invoke security-less version of the annotated object. Spring by default creates a security-enabled proxy of the annotated object and uses it for autowiring in the code, is there any way that i can achieve this using spring ?
An obvious way to do this would be to manually create proxy classes corresponding to each class for which i want this feature have those methods annotated and the implementation of these methods just delegate it to the actual object.
As an option in a case of JDK proxies you can get actual bean at runtime:
MyBean proxy;
if(AopUtils.isJdkDynamicProxy(proxy)) {
MyBean actualInstance = (MyBean) ((Advised)proxy).getTargetSource().getTarget()
}
actualInstance.doSomethingSecured(); // no advice related to this method will be called
// so your security annotation will be ignored (transactions, cache, and everething that requires AOP too...)
But from architectural point of view approach with manual proxies looks less error phrone (except if you absolutely sure that you do not need security and all another possible aspects too).
You can improve readability using generics:
MyBean actualInstance = extractProxyTarget(proxy, proxy.getClass());
actualInstance.doSomethingSecured();
Related
I add two annotations on the service method, after compiled, I found the method were compiled to a new class file, and I decompiled the generated class files and found the #CompileStatic were not work as wished.
Is is right or a bug of grails?
class FoobarService {
#grails.transaction.Transactional
#groovy.transform.CompileStatic
void foobar() {
....
}
}
The grails.transaction.Transactional annotation is a replacement for the traditional Spring org.springframework.transaction.annotation.Transactional annotation. It has the same attributes and features and works essentially the same, but it avoids an unfortunate side effect of using the Spring annotation.
The Spring annotation triggers the creation of a runtime proxy of the annotated class. Spring uses CGLIB to create a subclass of the target class (typically a Grails service) and an instance of the CGLIB proxy is registered as the Spring bean instead of registering a service instance directly. The proxy gets an instance of your service as a data variable.
Each method call is intercepted in the proxy, where it does whatever checks and/or setup is required based on the transaction settings, e.g. joining an existing transaction, creating a new one, throwing an exception because one isn't already running, etc. Once that's done, your real method is called.
But if you call another annotated method with different settings (e.g. the first method uses the default settings from #Transactional but the second should be run in a new separate transaction because it's annotated with #Transactional(propagation=REQUIRES_NEW)) then the second annotations settings will be ignored because you're "underneath" the proxy , inside the real instance of your service that the proxy is intercepting calls to. But it can't intercept direct calls like that.
The traditional workaround for this is to avoid direct calls and instead make the call on the proxy. You can't (at least not conveniently) inject the service bean into itself, but you can access the application context and access it that way. So the call that you would need in that situation would be something like
ctx.getBean('myService').otherMethod()
which works, but is pretty ugly.
The new Grails annotation works differently though. It triggers a reworking of the code via an AST transformation during compilation. A second method is created for each annotated method, and the code from the real method is moved inside there, in a GrailsTransactionTemplate that runs the code using the annotations settings. Once there, the code runs with the required transaction settings, but since every method is rewritten in this way, you don't have to worry about the proxy and where you're calling the methods from - there is no proxy.
Unfortunately there's a side effect that you're seeing - apparently the transformation happens in a way that isn't preserving the #CompileStatic annotation, so the code runs in dynamic mode. Sounds like a bug to me.
Using the Spring Security Plugin for Grails:
Version: 2.0-RC2
For my controllers I am using the #Secured annotation.
Is there a way to access the method parameter from the spring security expression.#paramName does not work for me.
#Secured(['ROLE_ADMIN',"hasRole('ROLE_USER') && #permissionService.updateAllowed( #myInstance )"])
def update(Bug myInstance) {
The problem: myInstance is null!
Software I am using:
Grails: 2.4.3
Intellij 14
JDK 8
I didn't notice that you were doing this in a controller - there's no support for method args in annotated controllers. The reason for this is that in traditional Spring Security, the annotation is applied to Spring Beans and the bean becomes proxied, and the proxy does the security checks before calling the method and only calls the real method if the checks pass. That works well with Spring MVC controllers because they're regular Java classes, and also in Grails services because there isn't much added to services by Grails - they're really just regular Groovy classes that are auto-registered as Spring Beans, and by default are made transactional.
But controllers are weird. There is actually one SpringMVC controller in any Grails app, and it's internally created and used by Grails. It interacts with the rest of SpringMVC, and delegates to the controller that best matches the url mappings rule for the current request to do its work, and it uses that to create the ModelAndView that Spring expects. Additionally, to support databinding, there's an AST transform that runs on your code during compilation which creates a no-arg method for each method with args, and that is what is called from the Grails internal request handling code. It does databinding and type conversions, and calls the "real" method to handle the request.
The support in Spring Security for working with method args depends on debug information being available in the compiled code, and usually this is not available because it's rarely needed - javac connects everything for us at compile time and getting the value of a method arg from outside of the method isn't often needed. Grails does keep that debug info - that's why this works in a service - but it looks like the AST isn't. It might be possible to get that working, but I have no idea if it is or what would be involved, and to be honest it would likely be a lot of work for a feature that wouldn't be used a lot.
But you can rework the check to pass the params to the service and let it lookup the Bug instance and then do its check. You can access the params from the service, so there's no need to pass anything as args:
import org.springframework.web.context.request.RequestContextHolder
...
def params = RequestContextHolder.requestAttributes.params
I've managed to get a workaround for the problem described in the comments to the accepted answer. Use #this in SpEL expression:
#Secured('#securityService.userCanEditOffer(#this)')
def edit(int id) {..}
Then create such methods in your service:
def userCanEditOffer(WebSecurityExpressionRoot webSecurityExpressionRoot) {
UrlMappingInfo urlMappingInfo = Holders.applicationContext.grailsUrlMappingsHolder.match(webSecurityExpressionRoot.request.forwardURI.substring(webSecurityExpressionRoot.request.contextPath.length()))
userCanEditOffer(Integer.valueOf(urlMappingInfo.params.id))
}
#Transactional(readOnly = true)
def userCanEditOffer(Integer id) { .. }
Inside ulrMappingInfo.params you'll have id, action and controller!
We're using the Grails spring security plugin:
http://grails.org/plugin/spring-security-core
I simply want to change the default access decision manager from the default AffirmativeBased to UnanimousBased. I do not see it documented anywhere in the plugin manual:
http://grails-plugins.github.io/grails-spring-security-core/docs/manual/
Does anyone know if it's possible to change this?
I added one additional voter, "myVoter" which is detected and working fine.
grails.plugins.springsecurity.voterNames = [
'myVoter', 'authenticatedVoter', 'roleVoter',
]
Based on Burt Beckwith's "Hacking the Grails Spring Security Plugin" [http://www.slideshare.net/gr8conf/hacking-the-grails-spring-security-plugins], it should be possible to simply provide a different implementation of the accessDecisionManager bean. Something like this:
accessDecisionManager(org.springframework.security.access.vote.UnanimousBased)
in resources.groovy
When I tried this, I had trouble with the constructor syntax in the bean definition. The access decision manager wants a list of voters in the constructor and I couldn't quote figure out how to get my voters defined in config.groovy as parameters to the constructor. I was about to derive my own decision manager (with parameterless constructor) from UnanimousBased when I stumbled upon the source code for AuthenticatedVetoableDecisionManager in the Grails Spring Security Plugin. This class splits the voters in half... anything deriving from AuthenticatedVoter will immediately fail if any are denied (e.g. AUTHENTICATED_FULLY family), but all other voters will pass if any are granted (e.g. RoleVoter). I wanted the AuthenticatedVoter functionality for my custom voter so I simply derived from AuthenticatedVoter (making sure to override all of the interface methods so I didn't accidentally get any base class functionality) and stuck with the default decision manager.
I am trying to secure Spring-Data repositories by using #PreAuthorize annotations on the my repository interface (since most methods are inherited) so that all methods get secured.
The result is that any custom methods included in my interface get security by all methods inherited by Spring-Data interfaces are not.
Applying the same thing on a simple component interface extending a superinterface will work properly.
I am not sure whether this is a Spring-Security or Spring-Data issue. I would appreciate some help figuring this out.
An example with unit tests for the working service setup and the non working Spring-Data repository can be downloaded at http://forum.springsource.org/showthread.php?133083-Using-PreAuthorize-on-SpringData-repositories. The failing testSuperRepositoryWithUser should get an AccessDeniedException, but the #PreAuthorize annotation does not apply on the JpaRepository interface.
By default spring wraps beans with JDK proxies. In this case annotations will work only for interface methods. So you need some more powerfull proxies (CGlib or AspectJ). I am not sure that it will fix your case "as is". You can try for CGlib:
<security:global-method-security ... proxy-target-class="true" />
For AspectJ:
<security:global-method-security ... mode="aspectj" />
In both cases you will need additional libraries and additional configuration.
See AOP Proxies for additional details.
From architectural point of view best place for security annotations is on your service methods. Consider following case: you have ServiceA.methodA() and ServiceB.methodB(). They use RepositoryC.methodC(). Your client want different security permissions for methodA() and methodB(). It will be impossible if your security layer is applied to repositories. So just apply your security annotations to services and there is no problem at all.
You can apply #PreAuthorize or similar annotations on all methods of a Repository interface by applying it to the interface and not the methods.
#PreAuthorize("hasRole('ROLE_SUPERUSER')")
public interface PersonnelRepository extends PagingAndSortingRepository<Person, Long>{}
You can also provide an annotation on a base repository that others inherit from which will secure the methods of inherited repositories.
#NoRepositoryBean
#RepositoryRestResource()
#PreAuthorize("hasAuthority('ROLE_USER')")
public interface BaseRepository<T, ID extends Serializable>
extends PagingAndSortingRepository<T, ID>{}
Now this repository will have the same security on all of it's methods as well.
public interface FooRepo extends BaseRepository <Foo, Long> {}
I have a custom attribute class derived from AuthorizationAttribute, which performs custom security on controller actions. The OnAuthorizationCore method depends on various other components (e.g. DAL) in order to ajudicate whether a user can invoke an action.
I'm using Autofac for dependency injection. The ExtensibleActionInvoker claims to be able to perform property injection on action filters. Setting an attribute's properties at runtime (which seems like a bad idea) will work in a simple unit test, but in a busy, multi-threaded web server it's bound to go wrong, and so this idea seems like an anti-pattern. Hence this question:
If my AuthorizationAttribute depends on other components in order to work correctly, what it the right [architecture] pattern in order to achieve this?
i.e. AuthorizationAttribute depends on IUserRepository... how should this relationship be resolved?
The ExtensibleActionInvoker claims to be able to perform property injection on action filters.
Correct - but don't confuse action filters with the attributes that might not implement them. The cleanest way to approach this in ASP.NET MVC is to split responsibilities, even though the MVC framework allows you to combine them.
E.g., use a pair of classes - an attribute class that holds data only:
// Just a regular old attribute with data values
class SomeAttribute : Attribute { ... }
And a filter that has dependencies injected:
// Gets dependencies injected
class SomeFilter : IActionFilter { ... }
SomeFilter just uses the typical approach of getting the SomeAttribute attribute from the controller or action method via GetCustomAttributes() to do whatever work is needed.
You can then use ExtensibleActionInvoker to wire up the filter:
builder.RegisterControllers(...).InjectActionInvoker();
builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();
builder.RegisterType<SomeFilter>().As<IActionFilter>();
It might be a little more code than you'd write using the attribute-as-filter approach, but the quality of the code will be better in the long run (e.g. by avoiding the limitations of attributes and the awkwardness of the Service Locator solutions.)
I would seem that the easiest way to achieve this is to bite the bullet and accept a dependency on autofac itself. While a dependency on the IoC is in itself an anti-pattern, it's somewhat more pallatable. You can implement a property as follows:
public class UserAuthorizeAttribute : AuthorizeAttribute
{
public IUserRepository CurrentUserService
{
get
{
var cpa = (IContainerProviderAccessor)HttpContext.Current.ApplicationInstance;
var cp = cpa.ContainerProvider;
return cp.RequestLifetime.Resolve<IUserRepository>();
}
}
}
...
There's no straight-forward way to do this prior to MVC2. There is an interesting technique detailed here: http://www.mattlong.com.au/?p=154. I'd suggest using the Common Service Locator to abstract over this and locate your DI container.
If you're using MVC 3 then you can use MVC Service Location
Constructor injection seems to be impossible w/o changing way of filter registration.
Even in Asp.Net Mvc3:
One place where dependency injection has been difficult in the past is inside the filter attributes themselves. Because the .NET framework runtime is actually responsible for creating these attribute instances, we cannot use a traditional dependency injection strategy.
So - next best thing is property injection (Mvc3 provides some support for that out of the box).
Here's a how to for doing that manually.
I personally use MvcExtensions. I'm fine with registering them in different way. Here's usage.
Another thing You might want to investigate is MvcTurbine project. In contrast to MvcExtensions project which is more general - MvcTurbine is primarily for providing dependency injection support.