2014-10-08 13 views
0

我試圖在基於java的配置上配置@EnableGlobalMethodSecurity,但註釋的方法被aspect忽略。我已經介紹了通常在同一個XML配置中遇到的所有問題,我的註釋位於根上下文的安全配置部分,我的服務類也在根上下文中進行管理。無法使@EnableGlobalMethodSecurity正常工作

以下TestService是一個包含我的@PreAuthorize註釋的接口,我也有一個相應的實現,我也嘗試過直接進行註釋。

AppInitializer.java

public class AppInitializer 
     extends AbstractAnnotationConfigDispatcherServletInitializer { 

    @Override 
    protected Class<?>[] getRootConfigClasses() { 
     return new Class[]{ 
      RootConfig.class, 
      SecurityConfig.class 
     }; 
    } 

    @Override 
    protected Class<?>[] getServletConfigClasses() { 
     return new Class[]{WebConfig.class}; 
    } 

    @Override 
    protected String[] getServletMappings() { 
     return new String[]{"/"}; 
    } 

} 

RootConfig.java

@Configuration 
@ComponentScan(basePackages = {"com.acme.app.service"}) 
public class RootConfig { 
} 

SecurityConfig.java

@Configuration 
@EnableWebMvcSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) 
public class SecurityConfig { 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) 
      throws Exception { 
     auth.inMemoryAuthentication() 
      .withUser("user").password("password").roles("USER").and() 
      .withUser("admin").password("pass").roles("USER", "ADMIN"); 
    } 

    @Configuration 
    public static class FormLoginWebSecurityConfigurerAdapter 
      extends WebSecurityConfigurerAdapter { 
     @Autowired 
     UserDetailsService userDetailsService; 
     @Override 
     protected void configure(HttpSecurity http) throws Exception { 
      http.authorizeRequests() 
       .antMatchers("/").permitAll() 
       .antMatchers("/static/**").permitAll() 
       .anyRequest().authenticated() 
       .and() 
       .formLogin() 
       .loginPage("/login").permitAll().defaultSuccessUrl("/") 
       .and().logout().logoutUrl("/logout") 
       .logoutSuccessUrl("/"); 
     } 
     @Override 
     protected UserDetailsService userDetailsService() { 
      return userDetailsService; 
     } 
    } 

    @Bean 
    public UserDetailsService userDetailsServiceBeanCreation() { 
     Collection<UserDetails> users = new ArrayList<>(); 
     users.add(getUser("user", "password", "USER")); 
     users.add(getUser("admin", "pass", "ADMIN", "USER")); 
     UserDetailsService uds = new InMemoryUserDetailsManager(users); 
     return uds; 
    } 

    private UserDetails getUser(String user, String pass, String... roles) { 
     // impl omitted... 
    } 

    @Configuration 
    @Order(1) 
    public static class ApiWebSecurityConfigurationAdapter 
      extends WebSecurityConfigurerAdapter { 
     @Autowired 
     UserDetailsService userDetailsService; 
     @Override 
     protected void configure(HttpSecurity http) throws Exception { 
      http.antMatcher("/api/**") 
       .authorizeRequests() 
       .anyRequest().authenticated() 
       .and() 
       .httpBasic().realmName("com.acme.app") 
       .and().sessionManagement(); 
     } 
     @Override 
     protected UserDetailsService userDetailsService() { 
      return userDetailsService; 
     } 
    } 
} 

WebConfig.java

@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages = {"com.acme.app.config", 
           "com.acme.app.controllers"}, 
       excludeFilters = { 
        @Filter(type = ASSIGNABLE_TYPE, 
          value = { 
           WebConfig.class, 
           SecurityConfig.class 
          }) 
       }) 
public class WebConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void addResourceHandlers(ResourceHandlerRegistry registry) { 
     registry.addResourceHandler("/static/**") 
       .addResourceLocations("/static/"); 
    } 

    @Bean 
    public CookieLocaleResolver getLocaleResolver() { 
     CookieLocaleResolver bean = new CookieLocaleResolver(); 
     bean.setCookieName("clientlanguage"); 
     bean.setCookieMaxAge(100000); 
     return bean; 
    } 

    @Override 
    public void addInterceptors(InterceptorRegistry registry) { 
     LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); 
     lci.setParamName("lang"); 
     registry.addInterceptor(lci); 
    } 

    @Bean 
    public TilesConfigurer getTilesConfigurer() { 
     CustomTilesInitializer ti = new CustomTilesInitializer(); 
     TilesConfigurer res = new TilesConfigurer(); 
     res.setCompleteAutoload(true); 
     res.setDefinitions("/WEB-INF/**/tiles.xml"); 
     return res; 
    } 

    @Override 
    public void configureViewResolvers(ViewResolverRegistry registry) { 
     registry.tiles(); 
     registry.enableContentNegotiation(new MappingJackson2JsonView()); 
    } 

    @Override 
    public void addViewControllers(ViewControllerRegistry registry) { 
     registry.addViewController("/").setViewName("home"); 
     registry.addRedirectViewController("/home", "/"); 
     registry.addViewController("/login").setViewName("login"); 
     registry.addViewController("/aboutme").setViewName("aboutme"); 
    } 

} 

TestService.java

public interface TestService { 
    @PreAuthorize("hasAuthority('ROLE_DUMMY_ROLE')") 
    BasicData getDataSecured(); 
} 

請注意,我也有我的POM彈簧AOP。

<dependency> 
    <groupId>org.springframework</groupId> 
    <artifactId>spring-aop</artifactId> 
</dependency> 
+0

註釋必須位於實現類中,而不是接口,並確保您的'WebConfig'也不掃描相同的組件。 – 2014-10-08 18:19:28

+0

@ M.Deinum我把它們放在兩個上面,但[參考文檔示例](http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle/#jc-方法)在界面上有它們。將包括我的'WebConfig' – 2014-10-08 18:24:26

+1

您的RootConfig包含在掃描時。我會(在這種情況下)排除所有'@ Configuration'類自動檢測。由於檢測,組件掃描再次實例化bean,因爲它們生活在不同的上下文中,因此這些bean不在安全方面。 – 2014-10-08 18:31:47

回答

4

當掃描爲DispatcherServlet做你的RootConfig是包括在內。

我會(在這種情況下)排除所有@Configuration類自動檢測。由於檢測,組件掃描再次實例化bean,因爲它們生活在不同的上下文中,因此這些bean不在安全方面。