我使用的是Spring 4.1.6和Spring Security 4.0.1
我试图将我的Spring和Spring Security XML配置转换为Java配置,并且已经在下面的例外中停留了很长一段时间......
... 25 more
Caused by: java.lang.IllegalStateException: org.springframework.security.config.annotation.ObjectPostProcessor is a required bean. Ensure you have used @EnableWebSecurity and @Configuration
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$1.postProcess(WebSecurityConfigurerAdapter.java:78)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:171)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:290)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:67)
at csc.oceanlaw.config.SecurityConfig$$EnhancerBySpringCGLIB$$f2885b2e.init(<generated>)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:369)
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:323)
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:41)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:105)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$80da63d.CGLIB$springSecurityFilterChain$0(<generated>)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$80da63d$$FastClassBySpringCGLIB$$2a6cb227.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$80da63d.springSecurityFilterChain(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 26 more
这是我的安全配置类:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity( prePostEnabled = true )
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String LOGIN_URL = "/login";
private static final String USER_BY_USERNAME_QUERY =
"select userName as username, password as password, 'true' as enabled " +
"from Users " +
"where (userName = ?)";
private static final String AUTHORITIES_BY_USERNAME_QUERY =
"select userName as username, role as authority " +
"from UserRoles " +
"where userName = ?";
private BasicDataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// Intercept-url config...
.authorizeRequests()
.antMatchers("/*").permitAll()
.antMatchers("/_a/**").hasRole("ROLE_USER")
.antMatchers("/_/**").hasRole("ROLE_USER")
.and()
.requiresChannel()
.anyRequest().requiresSecure()
.and()
// Login form config...
.formLogin()
.loginPage(LOGIN_URL)
.loginProcessingUrl("/j_spring_security_check")
.failureUrl("/login?err=1")
.successHandler(customAuthenticationHandler())
.usernameParameter("j_username")
.passwordParameter("j_password")
.and()
// Logout handling...
.logout()
.addLogoutHandler(logoutFilter())
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout=1")
.and()
// Exception handling config...
.exceptionHandling()
.accessDeniedPage("/unauthorized")
.authenticationEntryPoint(ajaxAwareAuthenticationEntryPoint())
.and()
.csrf()
.disable();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.usersByUsernameQuery(USER_BY_USERNAME_QUERY)
.authoritiesByUsernameQuery(AUTHORITIES_BY_USERNAME_QUERY)
.passwordEncoder(md5PasswordEncoder())
.dataSource(getDataSource());
};
@Bean
public AuthenticationFilter customAuthenticationHandler() {
return new AuthenticationFilter();
}
@Bean
public SecurityLogoutHandler logoutFilter() {
return new SecurityLogoutHandler();
}
@Bean
public AjaxAwareAuthenticationEntryPoint ajaxAwareAuthenticationEntryPoint() {
return new AjaxAwareAuthenticationEntryPoint(LOGIN_URL);
}
@Bean
public Md5PasswordEncoder md5PasswordEncoder() {
return new Md5PasswordEncoder();
}
@Bean
public DefaultRolesPrefixPostProcessor defaultRolesPrefixPostProcessor() {
return new DefaultRolesPrefixPostProcessor();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
public BasicDataSource getDataSource() {
dataSource = new PersistenceConfig().dataSource();
return dataSource;
}
public void setDataSource(BasicDataSource dataSource) {
this.dataSource = dataSource;
}
}
它似乎指出了安全配置,但是,它可能在配置类的其他地方。所以,下面是配置的其余部分......
Main Spring配置:
@Configuration
@ComponentScan(
basePackages = {
"myproject.model",
"myproject.web",
"myproject.dao",
"myproject.dao.jpa",
"myproject.config"
}
)
public class MainConfig {
/**
* Apache commons config bean.
* @return {@link CompositeConfiguration}
*/
@Bean(name="config")
public CompositeConfiguration compositeConfiguration() throws ConfigurationException {
PropertiesConfiguration textProps = null;
PropertiesConfiguration validationProps = null;
PropertiesConfiguration configProps = null;
textProps = new PropertiesConfiguration("olsdmText.properties");
textProps.setReloadingStrategy(new FileChangedReloadingStrategy());
validationProps = new PropertiesConfiguration("ValidationMessages.properties");
validationProps.setReloadingStrategy(new FileChangedReloadingStrategy());
configProps = new PropertiesConfiguration("olsdmSettings.properties");
configProps.setReloadingStrategy(new FileChangedReloadingStrategy());
CompositeConfiguration bean = new CompositeConfiguration();
bean.addConfiguration(textProps);
bean.addConfiguration(validationProps);
bean.addConfiguration(configProps);
bean.setDelimiterParsingDisabled(false);
bean.setListDelimiter('|');
return bean;
}
}
Spring MVC config:
@Configuration
@EnableWebMvc
public class WebMVCConfig extends WebMvcConfigurerAdapter {
@Inject org.apache.commons.configuration.Configuration config;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/docs/**").addResourceLocations("/docs");
registry.addResourceHandler("/resources/**").addResourceLocations("/resources");
}
@Bean
public ViewResolver viewResolver() {
ContentNegotiatingViewResolver bean = new ContentNegotiatingViewResolver();
List<ViewResolver> viewResolvers = new ArrayList<ViewResolver>();
// Apache Tiles view resolver...
UrlBasedViewResolver tilesResolver = new UrlBasedViewResolver();
tilesResolver.setViewClass(TilesView.class);
tilesResolver.setOrder(0);
viewResolvers.add(tilesResolver);
// Default view resolver as a fallback. Allow view names to be served with just
// .jsp extension rather than a tiles id. This is primarily for AJAX calls that
// request a JSP resource...
InternalResourceViewResolver defaultResolver = new InternalResourceViewResolver();
defaultResolver.setPrefix(new String("/WEB-INF/views/"));
defaultResolver.setSuffix(new String(".jsp"));
defaultResolver.setOrder(1);
viewResolvers.add(defaultResolver);
bean.setViewResolvers(viewResolvers);
return bean;
}
/**
* Sets Apache Tiles XML config file location.
* @return {@link TilesConfigurer}
*/
@Bean
public TilesConfigurer tilesConfig() {
TilesConfigurer bean = new TilesConfigurer();
String[] definitions = {"/WEB-INF/views/tiles/config/tiles-config.xml"};
bean.setDefinitions(definitions);
return bean;
}
@Bean
public CommonsMultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
@Bean
public PasswordGen passwordGen() {
return new PasswordGen();
}
@Bean
public Encrypt encrypt() {
return new Encrypt();
}
}
Datasource / JPA config:
@Configuration
@PropertySource("classpath:olsdmSettings.properties")
public class PersistenceConfig {
@Value("${jdbc.driverClassName}")
private String driverClassName;
@Value("${jdbc.databaseUrl}")
private String databaseUrl;
@Value("${jdbc.userName}")
private String userName;
@Value("${jdbc.passWord}")
private String passWord;
@Value("${jdbc.validationQuery}")
private String validationQuery;
@Value("${jdbc.testWhileIdle}")
private boolean testWhileIdle;
@Value("${jdbc.maxTotal}")
private int maxTotal;
@Value("${jdbc.maxIdle}")
private int maxIdle;
@Value("${jdbc.maxWailMillis}")
private int maxWailMillis;
/**
* Sets datasource configuration.
* @return {@link BasicDataSource}
*/
@Bean(name="dataSource")
public BasicDataSource dataSource() {
BasicDataSource bean = new BasicDataSource();
bean.setDriverClassName(driverClassName);
bean.setUrl(databaseUrl);
bean.setUsername(userName);
bean.setPassword(passWord);
bean.setValidationQuery(validationQuery);
bean.setTestWhileIdle(testWhileIdle);
bean.setMaxTotal(maxTotal);
bean.setMaxIdle(maxIdle);
bean.setMaxWaitMillis(maxWailMillis);
return bean;
}
/**
* Sets application {@link LocalContainerEntityManagerFactoryBean}
* @return {@link LocalContainerEntityManagerFactoryBean}
*/
@Bean
public LocalContainerEntityManagerFactoryBean emf() {
LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
bean.setDataSource(dataSource());
return bean;
}
/**
* Sets application {@link JpaTransactionManager}
* @return {@link JpaTransactionManager}
@Bean
public JpaTransactionManager jpaTransactionManager() {
JpaTransactionManager bean = new JpaTransactionManager();
bean.setEntityManagerFactory((EntityManagerFactory) emf());
return bean;
} */
@Bean
public PlatformTransactionManager transactionManager(){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(
emf().getObject());
return transactionManager;
}
/**
* Sets application {@link Jaxb2Marshaller}
* @return {@link Jaxb2Marshaller}
*/
@Bean
public Jaxb2Marshaller jaxb2Marshaller() {
Jaxb2Marshaller bean = new Jaxb2Marshaller();
bean.setPackagesToScan(new String("myproject.model"));
return bean;
}
//To resolve ${} in @Value
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
}
WebApplicationIntializer实施:
public class ApplicationInitializer implements WebApplicationInitializer {
private static final String CONFIG_LOCATION = "myproject.config";
private static final String MAPPING_URL = "/*";
@Override
public void onStartup(ServletContext container) throws ServletException {
WebApplicationContext context = getContext();
container.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic servlet =
container.addServlet("dispatcher", new DispatcherServlet(context));
servlet.setLoadOnStartup(1);
servlet.addMapping(MAPPING_URL);
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation(CONFIG_LOCATION);
return context;
}
}
非常感谢您提供任何帮助!
答案 0 :(得分:0)
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
public static final String CHARACTER_ENCODING = "UTF-8";
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{
WebMVCConfig.class,
PersistenceConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/*","/*"};
}
@Override
protected javax.servlet.Filter[] getServletFilters() {
final CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setEncoding(CHARACTER_ENCODING);
encodingFilter.setForceEncoding(true);
final OpenSessionInViewFilter openSessionInViewFilter = new OpenSessionInViewFilter();
return new Filter[] { encodingFilter, openSessionInViewFilter };
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
registerListener(servletContext);
}
private void registerListener(ServletContext servletContext) {
RequestContextListener requestContextListener = new RequestContextListener();
servletContext.addListener(requestContextListener);
}}
需要@Override Class [] getRootConfigClasses方法。这将使配置器类成为配置器bean。因此,您可以在配置类代码中使用@EnableWebSecurity和@Configuration。 希望这可以帮助! 像这样:
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{
WebMVCConfig.class,
PersistenceConfig.class};
}