2015-11-22 2 views
2

Я пытаюсь реализовать авторизацию на основе ACL для веб-приложения Spring. Как только я добавлю аннотацию @EnableGlobalMethodSecurity(prePostEnabled = true) к моему классу конфигурации безопасности, обработка сеанса транзакции Hibernate прерывается, и всякий раз, когда я пытаюсь сохранить объект, я получаю: Could not obtain transaction-synchronized Session for current thread. Я подозреваю, что я неправильно сконфигурировал что-то, связанное с кешем ACL, потому что проблема также исчезает, когда я удаляю связанные методы из моей конфигурации (при этом мой класс аннотируется с @EnableGlobalMethodSecurity(prePostEnabled = true)). Это соответствующие методы из моей конфигурации:Hibernate не может получить сеанс больше после включения @EnableGlobalMethodSecurity

@Bean 
public RoleHierarchyImpl roleHierarchy() { 
    RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl(); 
    roleHierarchy.setHierarchy("ROLE_ADMINISTRATOR > ROLE_MONITOR > ROLE_USER"); 
    return roleHierarchy; 
} 

/** 
* ACL audit logger (print ACL audits to console) 
* @return 
*/ 

@Bean 
ConsoleAuditLogger auditLogger(){ 
    return new ConsoleAuditLogger(); 
} 

/** 
* Caches ACL permissions to reduce database load 
* @return AclCache 
*/ 

@Bean 
SpringCacheBasedAclCache aclCache(){ 
    PermissionGrantingStrategy permissionGrantingStrategy = 
      new DefaultPermissionGrantingStrategy(auditLogger()); 


    return new SpringCacheBasedAclCache(cacheManager().getCache("aclCache"), permissionGrantingStrategy, aclAuthorizationStrategy()); 
} 

@Bean 
public CacheManager cacheManager() { 
    return new EhCacheCacheManager(ehCacheCacheManager().getObject()); 
} 

/** 
* Cache manager factory to create the cached based on the settings in "/WEB-INF/ehcache.xml" 
* @return EhCacheManagerFactoryBean 
*/ 

@Bean 
public EhCacheManagerFactoryBean ehCacheCacheManager() { 
    EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean(); 
    cmfb.setConfigLocation(new ServletContextResource(servletContext, "/WEB-INF/ehcache.xml")); 
    cmfb.setShared(true); 
    return cmfb; 
} 


@Bean 
AclAuthorizationStrategyImpl aclAuthorizationStrategy(){ 
    return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMINISTRATOR"), new SimpleGrantedAuthority("ROLE_ADMINISTRATOR"), new SimpleGrantedAuthority("ROLE_ADMINISTRATOR")); 
} 

@Bean 
AclPermissionEvaluator permissionEvaluator() { 
    return new AclPermissionEvaluator(aclService()); 
} 

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

@Bean 
BasicLookupStrategy lookupStrategy(){ 
    return new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), auditLogger()); 
} 

/** 
* Returns an expression handler based upon the specified role hierarchy and permission evaluator 
* @return 
*/ 

@Bean 
public DefaultMethodSecurityExpressionHandler expressionHandler(){ 
    DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler(); 
    expressionHandler.setPermissionEvaluator(permissionEvaluator()); 
    expressionHandler.setRoleHierarchy(roleHierarchy()); 
    return expressionHandler; 
} 

Я использую Spring 4.2.2, Hibernate EntityManager 5.0.3 и Spring Security 4.0.3. Кровавая вещь уже несколько часов меня била, и я просто не могу найти решение. Любые идеи, что мне здесь не хватает?

Приветствия, Jan

ответ

1

В конце концов я нашел решение, главным образом, из-за этого SO сообщение: Spring Hibernate - Could not obtain transaction-synchronized Session for current thread.

Автор заключает:

Не autowire бобов в GlobalMethodSecurityConfiguration => они не будут перехвачены должным образом после этого.

И это именно то, что произошло. Мой CustomUserDetailsService bean был автопроизведен в классе конфигурации безопасности, и транзакционный метод loadByUserName прекратил работать, потому что TransactionInterceptor проигнорировал этот компонент.

В основном я переместил все связанные с ACL файлы вместе с аннотацией @EnableGlobalMethodSecurity(prePostEnabled = true) в отдельный файл конфигурации, и все сразу все работало, как предполагается (включая авторизацию на основе ACL). Это дало мне болит голова, и я надеюсь, что смогу помочь кому-то с этим решением.

+0

Решенный очень похожий вопрос, используя тот же подход. Удалены все автообученные бобы из @EnableGlobalMethodSecurity и введены им с помощью ApplicationContextAware. – Amardeep

+0

Он работал для меня, когда я аннулировал классы обслуживания с помощью @ Lazy @ Autowired в моем классе CustomPermissionEvaluator. –

Смежные вопросы