WebSecurityConfigurers上的@Order必须是唯一的

时间:2014-05-29 10:04:55

标签: spring spring-mvc spring-security

我面临的问题是我的Spring应用程序有多个入口点。我粘贴在我的配置之下。

@Configuration 
@EnableWebMvcSecurity 
public class EntryPointsConfiguration {

@Configuration
@ComponentScan(basePackages = {"com.springapp.mvc"})
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    private ApplicationAuthenticationProvider authenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .httpBasic()
                .and()
                .antMatcher("/api/**")
                .authorizeRequests()
                    .anyRequest().hasAnyRole(Role.USER, Role.ADMIN);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider);
    }
}

@Configuration
@ComponentScan(basePackages = {"com.springapp.mvc"})
@Order(2)
public static class FormLoginConfigurationAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    private ApplicationAuthenticationProvider authenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .csrf()
                .disable();
        http
                .authorizeRequests()
                .antMatchers("/", "/codebase/**", "/resources/**", "/about", "/signup", "/signup/check").permitAll()
                .antMatchers("/admin*").hasAuthority(Role.ADMIN)
                .antMatchers("/home/**").hasAnyAuthority(Role.USER, Role.ADMIN)
                .antMatchers("/meetings*").hasAnyAuthority(Role.USER, Role.ADMIN)
                .antMatchers("/people*").hasAnyAuthority(Role.USER, Role.ADMIN)
                .anyRequest().authenticated();
        http
                .formLogin()
                .usernameParameter("j_username")   // default is username
                .passwordParameter("j_password")   // default is password
                .loginPage("/auth/login")    // default is /login with an HTTP get
                .failureUrl("/auth/failure")   // default is /login?error
                .loginProcessingUrl("/auth/login/process")    // default is /login with an HTTP post
                .permitAll()
        .and()
                .logout()
                .invalidateHttpSession(true)
                .logoutSuccessUrl("/auth/login")
                .logoutUrl("/auth/logout")
                .permitAll();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .eraseCredentials(false)
                .authenticationProvider(authenticationProvider);
    }
}

}

的web.xml

<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<display-name>Meeting Assistant</display-name>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>*.gif</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>*.png</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>*.xml</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>*.ico</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>userPanel.jsp</welcome-file>
</welcome-file-list>

<servlet>
    <servlet-name>mvc-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.springapp.mvc.configuration</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Servlet mvc-dispatcher:

<?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd">

<context:spring-configured />

<context:annotation-config />

<mvc:annotation-driven />

<tx:annotation-driven />

WebAppInitializer:

 public class SecurityWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

public SecurityWebApplicationInitializer() {}

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[]{EntryPointsConfiguration.FormLoginConfigurationAdapter.class,
                          EntryPointsConfiguration.ApiWebSecurityConfigurationAdapter.class,
                          WebSecurityConfig.class};
}

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

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

@Override
protected Filter[] getServletFilters() {
    CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
    characterEncodingFilter.setEncoding("UTF-8");

    return new Filter[] { characterEncodingFilter };
}


}

WebSecurityConfig:

public class WebSecurityConfig extends SecurityConfig {

   public WebSecurityConfig() {
       super("MeetingAssistant-security");
   }


}

WebConfiguration:

 @Configuration
 @EnableWebMvc
 @EnableSpringConfigured
 @ComponentScan(basePackages= "com.springapp.mvc")
 public class WebConfiguration extends WebMvcConfigurerAdapter {

@Bean
public UrlBasedViewResolver viewResolver() {
    UrlBasedViewResolver resolver = new UrlBasedViewResolver();
    resolver.setPrefix("/WEB-INF/pages/");
    resolver.setSuffix(".jsp");
    resolver.setViewClass(JstlView.class);
    return resolver;
}

@Bean
public MessageSource messageSource() {
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("messages");
    return messageSource;
}

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

@Bean
public LocaleResolver localeResolver() {
    CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
    cookieLocaleResolver.setDefaultLocale(StringUtils.parseLocaleString("en"));
    return cookieLocaleResolver;
}

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

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
    stringConverter.setWriteAcceptCharset(false);

    converters.add(new ByteArrayHttpMessageConverter());
    converters.add(stringConverter);
    converters.add(new ResourceHttpMessageConverter());
    converters.add(new SourceHttpMessageConverter());
    converters.add(new AllEncompassingFormHttpMessageConverter());

    converters.add(new Jaxb2RootElementHttpMessageConverter());

    converters.add(new MappingJackson2HttpMessageConverter());

}
}

堆栈追踪:

    java.lang.IllegalStateException: @Order on WebSecurityConfigurers must be unique. 
Order of 2 was already used, so it cannot be used on 
com.springapp.mvc.configuration.EntryPointsConfiguration$FormLoginConfigurationAdapter$$EnhancerByCGLIB$$a72c8c8c@74647003 too.

我尝试根据this answer更改注释但未成功。

我做错了什么?

顺便说一句,如果您能在Spring中推荐使用基于java的conf(REST,表单登录,OAuth2)的好的多入口点教程,我将非常感激。

欢呼声

编辑1:

好的,所以我按照你的要求更新了配置。尽管删除了@EnableWebSecurity,仍然会获得异常。 Spring Security已更新至3.2.4.RELEASE。

编辑2:

我认为提供相同的包可能会导致异常,因此我创建了2个不同的包并放置了2个AuthenticationProvider实现。

接下来,我改变了

ApiWebSecurityConfigurationAdapter

中的

basePackages=com.springapp.mvc.configuration.rest

FormLoginSecurityConfigurationAdapter中的

basePackages=com.springapp.mvc.configuration.form

这就是我得到的:

  Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.setObjectPostProcessor(org.springframework.security.config.annotation.ObjectPostProcessor)

我正在使用ASPECTJ模式的事务管理。这可不知所措?

顺便说一句。我使用的是Spring 4.0.0.RELEASE。

0 个答案:

没有答案