最近,我的同事告诉我,我的测试设置无法在带有oracle jdk的windows上运行。
如果我在下面发生异常时启用MethodSecurityConfig。如果我禁用MethodSecurityConfig它将正常工作。但方法安全对我来说是必要的。
Caused by: org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
如何使用@Transactional启用方法安全性?
SecurityConfig
@Configuration
public class TestSecurityConfig {
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
@Order(value = 93)
public static class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Autowired
RoleHierarchy roleHierarchy;
@Autowired
RoleVoter roleVoter;
@Autowired
AuthenticatedVoter authenticatedVoter;
@Autowired
AuthenticationManager authenticationManager;
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
methodSecurityExpressionHandler.setRoleHierarchy(roleHierarchy);
return methodSecurityExpressionHandler;
}
@Override
protected AccessDecisionManager accessDecisionManager() {
ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
expressionAdvice.setExpressionHandler(getExpressionHandler());
List<AccessDecisionVoter<?>> voters = Arrays.asList(
new PreInvocationAuthorizationAdviceVoter(expressionAdvice),
roleVoter,
authenticatedVoter
);
return new AffirmativeBased(voters);
}
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return authenticationManager;
}
}
@Configuration
@EnableWebSecurity(debug = false)
@Order(94)
public static class MainSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserService userService;
@Autowired
RoleVoter roleVoter;
@Autowired
AccessDecisionManager accessDecisionManager;
@Autowired
SecurityExpressionHandler<FilterInvocation> expressionHandler;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return userService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.accessDecisionManager(accessDecisionManager)
.expressionHandler(expressionHandler)
.anyRequest().permitAll()
;
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
AuthenticatedVoter authenticatedVoter(){
return new AuthenticatedVoter();
}
@Bean
RoleVoter roleVoter(RoleHierarchy roleHierarchy) {
return new RoleHierarchyVoter(roleHierarchy);
}
@Bean
AccessDecisionManager accessDecisionManager(AuthenticatedVoter authenticatedVoter, WebExpressionVoter webExpressionVoter, RoleVoter roleVoter) {
List<AccessDecisionVoter<?>> voters = Arrays.asList(authenticatedVoter, webExpressionVoter, roleVoter);
return new AffirmativeBased(voters);
}
@Bean
public WebExpressionVoter webExpressionVoter(SecurityExpressionHandler<FilterInvocation> webExpressionHandler) {
WebExpressionVoter webExpressionVoter = new WebExpressionVoter();
webExpressionVoter.setExpressionHandler(webExpressionHandler);
return webExpressionVoter;
}
@Bean
public SecurityExpressionHandler<FilterInvocation> webSecurityExpressionHandler(RoleHierarchy roleHierarchy) {
DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler();
defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy);
return defaultWebSecurityExpressionHandler;
}
@Bean
public MethodSecurityExpressionHandler methodSecurityExpressionHandler(RoleHierarchy roleHierarchy) {
DefaultMethodSecurityExpressionHandler methodSecurityExpressionHandler = new DefaultMethodSecurityExpressionHandler();
methodSecurityExpressionHandler.setRoleHierarchy(roleHierarchy);
return methodSecurityExpressionHandler;
}
@Bean
public RoleHierarchy roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
return roleHierarchy;
}
}
}
测试用例
@WebAppConfiguration
@ContextConfiguration(classes = {TestConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
public abstract class TestBase {
@Autowired
private WebApplicationContext context;
protected MockMvc mockMvc;
@Autowired
UserService userService;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.webAppContextSetup(context)
.apply(springSecurity())
.addFilters(new RequestContextFilter())
.build();
}
@WithUserDetails(value = "hurelhuyag")
@Test
public void test1(){
User user = userService.loadUserByUsername("hurelhuyag");
Assert.assertNotNull(user);
Assert.assertEquals("hurelhuyag", user.getLoginname());
}
}