1
votes

I use generally xml configuration in my Spring project under the three files:

applicationContext.xml: This file contains the main xml configuration: component scan, annotation-config and also an include of two other xml configuration files:

applicationContext-db.xml This file contains all database beans: dataSource, SessionFactory, ...

applicationContext-security.xml This file contains all spring security config.

I need to use also Spring Security ACL, for this I created a configuration class:

AclMethodSecurityConfiguration.java

package com.medkhelifi.tutorials.todolist.conf;

/**
/* all imports goes here.
**/

@Configuration
@ImportResource({"classpath*:conf/applicationContext-db.xml"})
@EnableGlobalMethodSecurity (prePostEnabled = true, securedEnabled = true)
public class AclMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {

    @Autowired
    DataSource dataSource;

    @Bean
    public MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        AclPermissionEvaluator permissionEvaluator = new AclPermissionEvaluator(aclService());
        expressionHandler.setPermissionEvaluator(permissionEvaluator);
        return expressionHandler;
    }


    @Bean
    public JdbcMutableAclService aclService() {
        return new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache());
    }

    @Bean
    public AclAuthorizationStrategy aclAuthorizationStrategy() {
        return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMIN"));
    }


    @Bean
    public PermissionGrantingStrategy permissionGrantingStrategy() {
        return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger());
    }


    @Bean
    public EhCacheBasedAclCache aclCache() {
        return new EhCacheBasedAclCache(
                    aclEhCacheFactoryBean().getObject(),
                    permissionGrantingStrategy(),
                    aclAuthorizationStrategy()
                    );
    }

    @Bean
    public EhCacheFactoryBean aclEhCacheFactoryBean() {
        EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean();
        ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject());
        ehCacheFactoryBean.setCacheName("aclCache");
        return ehCacheFactoryBean;
    }

    @Bean
    public EhCacheManagerFactoryBean aclCacheManager() {
        return new EhCacheManagerFactoryBean();
    }

    @Bean
    public LookupStrategy lookupStrategy() {
        return new BasicLookupStrategy(
                    dataSource,
                    aclCache(),
                    aclAuthorizationStrategy(),
                    new ConsoleAuditLogger());
    }
}

My problem is the datasource autowired into Configuration file is null, I don't kwno if i missed something.

My XMLs files are all under: src/main/resources/conf/

There is my datasource bean definition in applicationContext-db.xml

<!--        DATASOURCE                      -->
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${database.driver}"/>
    <property name="url" value="${database.url}"/>
    <property name="username" value="${database.username}"/>
    <property name="password" value="${database.password}"/>
</bean>

I already used this bean into Sessionfactory bean defined in the same applicationContext-db.xml file.

PS: When I remove the extended class GlobalMethodSecurityConfiguration my datasource is defined, but I need this org.springframework.security.config.annotation.method.configurationclass to set up my Spring Security ACL configuration.

2
Is your com.medkhelifi.tutorials.todolist.conf available for component scan? I mean does spring able to find your configuration class to inject Datasource? - Vasif
Yes I use: <context:component-scan base-package="com.medkhelifi.tutorials.todolist"/> in my applicationContext.xml - medkhelifi
Can you try it without classpath? Like as {"conf/applicationContext-db.xml"} - Vasif
No by using your proposition I get: IOException parsing XML document from ServletContext resource [/conf/applicationContext-db.xml]; - medkhelifi
Can u put full log file? It is not able to find given file or not able to parse it? - Vasif

2 Answers

1
votes

I found a way to define my datasource bean by using the BeanFactoryAware interface. BeanFactoryAware is used to inject the BeanFactory object. This way we get access to the BeanFactory which created the object.

@EnableGlobalMethodSecurity (prePostEnabled = true, securedEnabled = true)
@Configuration
@ImportResource({"classpath:/conf/applicationContext-db.xml"})
public class AclMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration implements BeanFactoryAware {

    DataSource dataSource;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.dataSource = beanFactory.getBean("dataSource", DataSource.class);
    }
    // rest of code goes here 
}

I read that if we use this technic that means we are doing something wrong, I'll continue searching for a proper solution.

0
votes

Please rename your bean as name="dataSource"