2012-01-25 39 views
1

在我的web.xmlspring 3.1 with spring 4 with spring security 3.1:如何确保在spring安全性之前提供交易建议。

openSessionInView org.springframework.orm.hibernate4.support.OpenSessionInViewFilter

 <init-param> 
      <param-name>singleSession</param-name> 
      <param-value>false</param-value> 
     </init-param> 
    </filter> 

<!-- open session in view mapping --> 
<filter-mapping> 
    <filter-name>openSessionInView</filter-name> 
    <url-pattern>/*</url-pattern> 
    <dispatcher>FORWARD</dispatcher> 
    <dispatcher>REQUEST</dispatcher> 
    <dispatcher>ERROR</dispatcher> 
</filter-mapping> 

在我的applicationContext-main.xml中我有

<aop:config> 
    <aop:pointcut id="serviceMethods" 
     expression="execution(* com.utility.*.*(..))" /> 
    <aop:advisor advice-ref="ownership.methodSecurityInterceptor" 
     pointcut-ref="com.serviceMethods" order="2" /> 
</aop:config> 

在我applicationContext-spring-security.xml我有以下bean定义

我MCL服务。

public class CustomMethodDefinitionServiceImpl 
     implements MethodSecurityMetadataSource { 
    private final MclDao mclDao; 

    @Autowired(required = true) 
    public CustomMethodDefinitionServiceImpl(final MclDao mclDao) { 
     super(); 
     this.mclDao = mclDao; 
    } 

    @Override 
    @Transactional(readOnly=true, propagation=Propagation.REQUIRED) 
    public Collection<ConfigAttribute> getAllConfigAttributes() { 
     return this.getMetaDataSource().getAllConfigAttributes(); 
    } 

    @Override 
    public Collection<ConfigAttribute> getAttributes(final Method method, final Class<?> targetClass) { 
     return ((MapBasedMethodSecurityMetadataSource) this.getMetaDataSource()).getAttributes(method, targetClass); 
    } 

    @Override 
    public Collection<ConfigAttribute> getAttributes(final Object obj) 
      throws IllegalArgumentException { 
     return this.getMetaDataSource().getAttributes(obj); 
    } 

    @Override 
    public boolean supports(final Class<?> clazz) { 
     return clazz.isInterface(); 
    } 


    public SecurityMetadataSource getMetaDataSource() { 
     final List<MethodControlList> methodConrolLists = this.mclDao.getAllMethodControlList(); 
     final List<ConfigAttribute> configList = new LinkedList<ConfigAttribute>(); 
     final Map<String, List<ConfigAttribute>> methodMap = new LinkedHashMap<String, List<ConfigAttribute>>(); 
     for (final MethodControlList mcl : methodConrolLists) { 
      final StringBuilder serviceNameBuilder = new StringBuilder(); 
      final ClassMethod classMethod = mcl.getClassMethod(); 
      serviceNameBuilder.append(classMethod.getClassName()); 
      serviceNameBuilder.append("."); 
      serviceNameBuilder.append(classMethod.getMethodName()); 
      final List<Role> roles = this.mclDao.getAllRoleThatCanAccessClassAndMethod(classMethod.getClassName(), classMethod.getMethodName()); 
      for (final Role role : roles) { 
       configList.add(new SecurityConfig(role.getAuthority())); 
      } 
      methodMap.put(serviceNameBuilder.toString(), configList); 
     } 
     return new MapBasedMethodSecurityMetadataSource(methodMap); 
    } 
} 

我MclDao

public List<Role> getRolesThatCanAccessClassAndMethod(final String className, final String methodName) {  
    this.sessionFactory.getCurrentSession() 
          .getNamedQuery("getRolesThatCanAccessMethod") 
          .setString("className", className) 
          .setString("methodName", methodName) 
          .list(); 
} 

当我启动应用程序我得到这个错误。

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'methodSecurityInterceptor' defined in class path resource [applicationContext-spring-security.xml]: Invocation of init method failed; nested exception is org.springframework.orm.hibernate4.HibernateSystemException: No Session found for current thread; nested exception is org.hibernate.HibernateException: No Session found for current thread 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
    at org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor.getAdvice(AbstractBeanFactoryPointcutAdvisor.java:85) 
    at org.springframework.aop.aspectj.AspectJProxyUtils.isAspectJAdvice(AspectJProxyUtils.java:67) 
    at org.springframework.aop.aspectj.AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(AspectJProxyUtils.java:49) 
    at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.extendAdvisors(AspectJAwareAdvisorAutoProxyCreator.java:101) 
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:88) 
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:68) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:359) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1461) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
    ... 22 more 
Caused by: org.springframework.orm.hibernate4.HibernateSystemException: No Session found for current thread; nested exception is org.hibernate.HibernateException: No Session found for current thread 
    at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:199) 
    at org.springframework.orm.hibernate4.HibernateExceptionTranslator.convertHibernateAccessException(HibernateExceptionTranslator.java:50) 
    at org.springframework.orm.hibernate4.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:37) 
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58) 
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) 
    at $Proxy73.getAllMethodControlList(Unknown Source) 
    at com.util.security.service.impl.CustomMethodDefinitionServiceImpl.getMetaDataSource(CustomMethodDefinitionServiceImpl.java:63) 
    at com.util.security.service.impl.CustomMethodDefinitionServiceImpl.getAllConfigAttributes(CustomMethodDefinitionServiceImpl.java:43) 
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.afterPropertiesSet(AbstractSecurityInterceptor.java:137) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) 
    ... 39 more 
Caused by: org.hibernate.HibernateException: No Session found for current thread 
    at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97) 
    at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:883) 
    at com.util.security.dao.impl.MclDaoHibernateImpl.getAllMethodControlList(MclDaoHibernateImpl.java:88) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155) 
    ... 47 more 

我猜测这是因为在启动时验证配置属性之前web.xml中得到调用,比我将如何确保在应用程序启动时自己是一个会话?

**尝试下面的建议,加入@Transactional,仍然有同样的问题。 ** **我使用order = 1进行注释驱动,并使用aop 2,所以它将首先进行事务处理,但似乎不起作用。

回答

1

openSessionInView过滤器未激活时,getCurrentSession()应在现有事务中调用。

因此,为确保创建交易,您还需要制定服务方法@Transactional(或将DAO方法的传播更改为REQUIRED)。

+0

嗨,谢谢。我试过了,没有工作。我添加了tx:annotation-driven并在同一个xml中定义了这个bean。另外,我还在getAllConfigAttributes –

+0

之前添加了@Transactional(readOnly = true,propagation = Propagation.REQUIRED),并将此更新从7.0.23版本升级到tomcat 7.0.25。我需要使mclDao成为mclService。 –