Results 1 to 2 of 2

Thread: Secured annotation with interfaces

  1. #1
    Join Date
    Mar 2011
    Posts
    2

    Default Secured annotation with interfaces

    I get an exception while trying to have secured methods in a class that implements an interface (it doesn't even seem to matter if the method with @Secured annotation is in the interface and the class implements or only the class itself). Security core and config versions are both 3.0.5.RELEASE. Anyone knows what's going on in here?


    Here's an example:

    appConfig.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:security="http://www.springframework.org/schema/security"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
                               http://www.springframework.org/schem...-beans-3.0.xsd
                               http://www.springframework.org/schema/context
                               http://www.springframework.org/schem...ontext-3.0.xsd
                               http://www.springframework.org/schema/tx
                               http://www.springframework.org/schem...ing-tx-3.0.xsd
              http://www.springframework.org/schema/security
              http://www.springframework.org/schema/security/spring-security-3.0.5.xsd">
    <import resource="securityConfig.xml"/>
    	<bean id="secureThing" class="foo.SecureClass" />
    	<bean id="injectedThing" class="foo.InjectedClass" p:secureThing-ref="secureThing" />
    </beans>
    securityConfig.xml

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <b:beans xmlns="http://www.springframework.org/schema/security"
        xmlns:b="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-3.0.xsd
                            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
     <global-method-security secured-annotations="enabled" />
    </b:beans>
    Injected class

    Code:
    package foo;
    
    public class InjectedClass {
    	
    	private SecureClass secureThing;
    
    	public SecureClass getSecureThing() {
    		return secureThing;
    	}
    
    	public void setSecureThing(SecureClass secureThing) {
    		this.secureThing = secureThing;
    	}
    
    }
    Secure interface

    Code:
    package foo;
    
    import org.springframework.security.access.annotation.Secured;
    
    public interface ISecureInterface {
    	
    	@Secured("ROLE_X")
    	void secureMethod();
    
    }
    Secure class

    Code:
    package foo;
    
    import org.springframework.security.access.annotation.Secured;
    
    public class SecureClass implements ISecureInterface {
    
    
    	@Secured("ROLE_X")
    	public void secureMethod() {
    		System.out.println("Hello world!");
    	}
    
    }
    Starter

    Code:
    package foo;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Starter {
    	
    	public static void main(String[] args) {
    		ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:appConfig.xml");
    		InjectedClass mySecureThing = context.getBean("injectedThing", InjectedClass.class);
    		mySecureThing.getSecureThing().secureMethod();
    	}
    
    }
    Result:

    Code:
    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'injectedThing' defined in URL [file:/C:/eworkspace/sec/target/classes/appConfig.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type '$Proxy5 implementing foo.ISecureInterface,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised' to required type 'foo.SecureClass' for property 'secureThing'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [$Proxy5 implementing foo.ISecureInterface,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [foo.SecureClass] for property 'secureThing': no matching editors or conversion strategy found
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:574)
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    	at foo.Starter.main(Starter.java:11)
    Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type '$Proxy5 implementing foo.ISecureInterface,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised' to required type 'foo.SecureClass' for property 'secureThing'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [$Proxy5 implementing foo.ISecureInterface,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [foo.SecureClass] for property 'secureThing': no matching editors or conversion strategy found
    	at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:462)
    	at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:499)
    	at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:493)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1363)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1322)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1076)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    	... 11 more
    Caused by: java.lang.IllegalStateException: Cannot convert value of type [$Proxy5 implementing foo.ISecureInterface,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [foo.SecureClass] for property 'secureThing': no matching editors or conversion strategy found
    	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:231)
    	at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:447)
    	... 17 more
    Last edited by Luke Taylor; Mar 13th, 2011 at 03:36 PM. Reason: Added code tags

  2. #2
    Luke Taylor is offline Senior Member Acegi Security System TeamSpring Team
    Join Date
    Aug 2004
    Location
    Glasgow, Scotland
    Posts
    3,449

    Default

    Spring AOP uses interfaces by default, so when you add a security interceptor, the resulting bean will implement the interfaces that your bean implements. It won't be an instance of the same specific class as the original bean, unless you set the "proxy-target-class" flag on the "global-method-security" element.

    It's generally recommended that you program to an interface instead, to avoid this kind of issue.
    Spring - by Pivotal
    twitter @tekul

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •