A simple pointcut expression in Spring - spring

I'm using Spring security 3.2.0 with the same version of the Spring framework. Spring security works well in my project. In order to protect methods in my DAO classes (and others), I want to use the following pointcut approach (in the spring-security.xml file).
<global-method-security>
<protect-pointcut expression="execution(*controller.*.*(..))" access="ROLE_ADMIN"/>
</global-method-security>
I expect the pointcut expression as specified to protect all the methods in all classes inside the controller package and to be accessed only by the users who have the authority ROLE_ADMIN as specified.
But when I try to use this expression, the process terminates with following exception on saving my spring-security.xml file.
PropertyAccessException 1:
org.springframework.beans.MethodInvocationException: Property
'pointcutMap' threw exception; nested exception is
java.lang.IllegalArgumentException: Pointcut is not well-formed:
expecting 'name pattern' at character position 26
execution(controller..*(..))
^
I'm trying to follow the approach as specified by the reference document in the Adding Security Pointcuts using protect-pointcut sub-section of the 3.4.1 The <global-method-security> Element section.
What is correct expression syntax in this scenario?
EDIT:
Adding Security Pointcuts using protect-pointcut
The use of protect-pointcut is particularly powerful, as it allows you to apply security to many beans with only a simple declaration. Consider the following example:
<global-method-security>
<protect-pointcut expression="execution(* com.mycompany.*Service.*(..))" access="ROLE_USER"/>
</global-method-security>
This will protect all methods on beans declared in the application context whose classes are in the com.mycompany package and whose class names end in "Service". Only users with the ROLE_USER role will be able to invoke these methods. As with URL matching, the most specific matches must come first in the list of pointcuts, as the first matching expression will be used. Security annotations take precedence over pointcuts.
Copy & pasted the section explained in the reference document (as someone may find it to be tedious to scroll the document).

Try with this expression :
<protect-pointcut expression="execution(* your.package.controller.*.*(..))" access="ROLE_ADMIN"/>

Related

Spring pointcut XML expression on custom annotation

I have a custom annotation as follows:
#Inherited
#Target({ElementType.TYPE, ElementType.METHOD})
#Retention(RetentionPolicy.RUNTIME)
public #interface MyCustomAnnotation {
}
In Spring XML configuration I have the following:
<aop:pointcut id="fooPointcut" expression="#annotation(com.foo.blah.MyCustomAnnotation)"/>
This will only match on method annotations. How do I tweak the spel to also capture type/class annotations?
Use #within(com.foo.blah.MyCustomAnnotation) to
limit matching to join points within types that have the given annotation
A combined pointcut expression would become:
#annotation(com.foo.blah.MyCustomAnnotation) || #within(com.foo.blah.MyCustomAnnotation)
See Join Point Matching based on Annotations in the AspectJ 5 Developer's Notebook for further reference. Also note, that Spring's AOP doesn't support full AspectJ pointcuts, only a limited subset.
Also note that #annotation(com.foo.blah.MyCustomAnnotation) in AspectJ would match
all join points where the subject of the join point has the given annotation
meaning that it would match method-execution as well as method-call. In Spring AOP it only matches method-execution though, but it's better to write pointcut expressions that are valid in a broader scope as well, so don't forget to use an execution(...) pointcut too to restrict the pointcut.

AOP: A combination of two #annotation clauses is not working

I'm trying to write a pointcut, which shall hit for every method marked with certain annotation except the ones marked with another annotation.
But the following is not working:
<aop:aspect ref="...">
<aop:before method="execute" pointcut="#annotation(MyAnnotation1)
and not #annotation(MyAnnotation2)"/>
</aop:aspect>
Will you please advise what i'm doing wrong?..
The Spring AOP documentation states
When combining pointcut sub-expressions, && is awkward within an XML
document, and so the keywords and, or and not can be used in place of
&&, || and ! respectively.
However, you're not allowed to bind parameters with negation. If you're saying it doesn't exist, what value would be passed as an argument?
Change it to
<aop:before method="execute" pointcut="#annotation(MyAnnotation1)
and not #annotation(com.example.MyAnnotationName)"/>
So MyAnnotation1 can refer to a parameter, but the other can't. As such, you need to specify the fully qualified name of the annotation type. A corresponding pointcut would look like
//#Pointcut(value = "#annotation(MyAnnotation1) && !#annotation(com.example.MyAnnotationName)")
public void yesNotNo(MyAnnotation1 MyAnnotation1) {
}

Spring AOP IllegalArgumentException: Cannot convert value of type [$Proxy12

I am trying to configure one advice in an existing spring project.
Following configuration works fine for a single package but when pointcut expression try to apply that advice on all packages its giving following error.
My Configuration:
<aop:config>
<aop:pointcut id="loggingPointcut" expression="execution(* com.abc.businessprocess.operation..*.execute(..))" />
<aop:advisor id="methodLoggingAdvisor" advice-ref="methodLoggingAdvice" pointcut-ref="loggingPointcut" />
</aop:config>
I tried with annotation also but it was giving same error.
I tried with CGLIB also even after using that its giving same error.
Error:
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy12 implementing com.fmr.ast.common.businessprocess.util.Timeable,com.fmr.ast.common.businessprocess.operation.Operation,com.fmr.commons.taskmanager.core.Task,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.fmr.ips.businessprocess.operation.goalsetup.GetLeveledIRGExpInc] for property 'getRawDetailedLeveledExpInc'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy12 implementing com.fmr.ast.common.businessprocess.util.Timeable,com.fmr.ast.common.businessprocess.operation.Operation,com.fmr.commons.taskmanager.core.Task,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.fmr.ips.businessprocess.operation.goalsetup.GetLeveledIRGExpInc] for property 'getRawDetailedLeveledExpInc': no matching editors or conversion strategy found
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:391)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1289)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1250)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
... 33 more
Caused by: java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy12 implementing com.fmr.ast.common.businessprocess.util.Timeable,com.fmr.ast.common.businessprocess.operation.Operation,com.fmr.commons.taskmanager.core.Task,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.fmr.ips.businessprocess.operation.goalsetup.GetLeveledIRGExpInc] for property 'getRawDetailedLeveledExpInc': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:231)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:138)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:386)
... 37 more
Looking at the exception trace this is what I suspect:
GetLeveledIRGExpInc is a concrete class that implements three interfaces: Timeable, Operation, Task. You have a bean of this type declared in your context, which gets proxied because of your AOP config. This means that the runtime type of the bean won't be GetLeveledIRGExpInc any more, it will be $Proxy12 (JDK proxy) which still implements the above three interfaces, but is not a subtype of the concrete class GetLeveledIRGExpInc.
There is another bean somewhere in your context that needs a bean of this type to be injected into a property named getRawDetailedLeveledExpInc. When Spring tries to inject the proxied bean into that property, it fails, because the property's type is incompatible with the bean's runtime type.
The fundamental problem is that you try to apply a very generic logging aspect using JDK proxying mechanism which can only advise methods declared on interfaces. Try using <aop:config proxy-target-class="true"> so that classes without implemented interfaces can be advised as well. This would resolve the above detailed problem, as the generated CGLIB proxy for GetLeveledIRGExpInc will actually be a subtype of it. (Don't forget to add cglib to your dependencies for this to work.)

Spring Framework (V2.5) - Using actionpath in ref attribute in a bean definition

I am a pretty newcomer for Spring Framework.
This is regarding referencing another bean using ref attribute.
I have a bean definition for an action class like below.
<bean name="/abc" class="com.example.actions.Action" scope="singleton">
<property name="businessLogic" ref="/pqr"/>
</bean>
I am trying to inject another bean into this bean using ref attribute (ie "/pqr").
<bean name="/pqr" class="com.example.businesslogic.PqrBL" scope="prototype" />
Now my question how normal is it to use name="/pqr" kind of a notation for a bean which is not a definition for some action class ? By convention is it an acceptable normal scenario ?
PS: please let me know if information provided is incomplete or the question is not clear.
Thanks
The Spring reference states that
The convention is to use the standard Java convention for instance field names when
naming beans. That is, bean names start with a lowercase letter, and are camel-cased from
then on. Examples of such names would be (without quotes) 'accountManager',
'accountService', 'userDao', 'loginController', and so forth.
It is not normal to use "/pqr" as a bean name but you can do it . I would prefer using more user friendly names to the beans than using a "path" .
Check here for the convention .

Conditions in Spring expression language(SpEL) used in bean definition

As far SpEL is used in Spring 3.0,
I would like to ask, is it possible to do following(in bean definition .xml):
<c:choose>
<c:when test="#{prop=='a'}">
<bean class="BeanA"/>
</c:when>
<c:otherwise>
<bean class="BeanB"/>
</c:otherwise>
</c:choose>
Someth. like in jstl.
Thank you for help.
Environment profiles/Environment specific beans will be available in Spring 3.1 which should be released shortly - so you might want to wait for that.
There is no built in support for conditional beans in Spring 3.0. However, it could be achieved by using PropertyPlaceholderConfigurers and/or FactoryBeans.
There's no conditional mechanism for XML Spring bean defintion files.
However, maybe this would work:
<bean class="#{prop=='a' ? BeanA : BeanB}"/>
But even if this approach worked, it wouldn't be the most readable one. My suggestion would be to use different set of XML configuration files and pick them depending on some global settings. Naturally you would put all the common beans (i.e. these whose definition is always the same) in a separate file and have it always included.
it is not a question of using spel, but more of XML,afaik you can't do this in XML (but xslt)
the proper spring way for this scenario might be http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-class in combination with a "parent" interface for BeanA and BeanB
you could pass the parameter (system ? runtime specific ?) to the factory, which would create either BeanA or BeanB

Resources