Using #PreAuthorize on SpringData repositories - spring-security

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> {}

Related

Change AccessDecisionManager to UnanimousBased in Grails Spring Security Plugin

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.

how to invoke unsecured proxy while using spring security annotations?

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();

Advantages of WebServiceGatewaySupport vs WebServiceTemplate

I have to implement a webservice client using Spring WS.
I've read the documentation at http://static.springsource.org/spring-ws/site/reference/html/client.html but it's not clear to me what are the advantages of extending WebServiceGatewaySupport versus directly using WebServiceTemplate in my service class.
As far as I can tell from the source, the WebServiceGatewaySupport only has a couple of wrapper methods for the WebServiceTemplate and some initialization support.
So why should I extend WebServiceGatewaySupport instead of directly using a WebServiceTemplate ?
Thank you!
I think this sums it all up (found in the client reference you linked):
Alternatively, consider deriving from Spring-WS's
WebServiceGatewaySupport convenience base class, which exposes
convenient bean properties to enable easy configuration. (You do not
have to extend this base class... it is provided as a convenience
class only.)
So, if the WebserviceTemplate offers all you need, that'll probably suffice. If you need anything extra you can use the WebServiceGatewaySupport as an example on how to wrap your own convenience methods around the WebserviceTemplate.
In my client software, I just configure the WebserviceTemplate in my #Configuration class like this:
#Bean
public WebServiceTemplate webServiceTemplate() {
WebServiceTemplate template = new WebServiceTemplate();
template.setMessageFactory(messageFactory());
template.setDefaultUri(defaultUri);
template.setMarshaller(marshaller());
template.setUnmarshaller(marshaller());
template.setInterceptors(new ClientInterceptor[] {interceptor()});
return template;
}
(All the method calls are references to other methods in the configuration which aren't that relevant in this example).
I can use that bean everywhere in my code to send messages.

Using CDI to inject a Data Access Object

Assuming I have a data access object that I've already written, I'd like to be able to use CDI to inject that into say, a service class. Furthermore, I have two implementations of that DAO.
My understanding of CDI is that I'd have to annotate my DAO implementation class so that CDI would know which implementation to inject.
The problem is, the DAO is in a .jar file. By annotating it with CDI annotations, I'm using JavaEE imports in a non-JavaEE class.
For example, let's say I have the following class
public class BusinessService {
#Inject #SomeMybatisQualifier AccountDAO accountDao;
...
}
The #Inject annotation comes from javax.inject.Inject. Now, this service class is dependent on a JavaEE environment.
Can someone please explain to me what I'm missing? How do I inject a non-annotated class into another non-annotated class? This is fairly simple with Spring.
I agree with LightGuard if there's enough classes. But for a couple, why not just produce them with #Produces?
Here's a decent example of implementing your own producer:
Depedency inject request parameter with CDI and JSF2
You should be able to write return new MyObject(); and you can add whatever qualifiers you want
Not sure what's unclear but here's the gist of things: For CDI to scan a jar for beans it must have a beans.xml. Else it will not be scanned and thus not available for injects.A String is not available either. If you try to inject a String say;
#Inject
String myString;
CDI will have no clue what to give you just like your jar. But I know what String I want (a requestparam) and I can let CDI know as well. How? Well I supply a qualifier #RequestParam to my producer (see example again) and now when I want to use it in client code I do it like this:
#Inject
#RequestParam
String myString;
You can do the same thing. Have a producer and just create a new instance of whatever you need and then return it. Now CDI will know just how to dependency inject that particular bean.
Now say you have 40 classes. Then it gets messy to produce them and you want to make sure it gets scanned instead. Then you write your own little extension, observe when CDI is about to scan and instruct it to scan additional jars. Such extension is probably easy to write but I don't know the details because I have not written any extensions like it
By far, the easiest thing would be to create a CDI extension to add the classes in the jar (because there's no beans.xml in that jar so it won't be picked up by CDI) and add additional qualifiers to the metadata.

Spring Security 3: #PostFilter not working

Hi
I am new to Spring Security 3 and was trying out #PostFilter on a method declared in an Interface but the returned Collection is not getting filtered.
Here is the code:
public interface IProductService {
#PostFilter("(!filterObject.customersOnly) or (filterObject.customersOnly and hasRole('ROLE_USER'))")
Collection<Category> getCategories();
}
customerOnly is a boolean attribute in a domain object Category.
I've added the following element on xyz-security.xml:
<global-method-security pre-post-annotations="enabled" />
Could someone help me understand what am i missing?
Thanks
The typical causes for this are:
AspectJ and/or CGLIB JARs are not in your classpath.
You have the annotation on an interface OR on a class (review the Spring AOP docs to determine which is supported for which AOP implementation).
You have added the Spring Security configuration to a different ApplicationContext than where you have declared your secured beans (for example, you are trying to secure a bean in your *-servlet.xml file, when your Spring Security configuration is declared by the ContextLoaderListener).
You have removed or altered the declaration so that the annotated bean is not processed by the same ApplicationContext where Spring Security is configured.
If none of these suggestions applies, please enable DEBUG logging and watch application startup to see if the bean annotation is processed at all.
As an aside, I have had many readers report similar flavors of this problem - the source code for this sample does work, but in all cases it has been true that readers have subsequently changed one of the above 4 items, causing the sample code to "break" ;)

Resources