我有一个小项目hibernate
+ jpa
,Spring
,Spring MVC
(没有SpringBoot
)。现在我正在尝试添加Spring Security
。
UserDetailsServiceImpl.class
:
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
Service<Account> accountService;
@Override
public UserDetails loadUserByUsername(String mail) throws UsernameNotFoundException {
Account account = new Account();
account.setMail(mail);
Account foundedAccount = accountService.readByObj(account);
if (foundedAccount == null) {
throw new UsernameNotFoundException("Account not found");
}
return new User(foundedAccount.getMail(), foundedAccount.getPassword()
, true, true, true, true,
Collections.singleton(new SimpleGrantedAuthority("ROLE_" + foundedAccount.getRole())));
}
}
SecurityConfig.class
:
@EnableWebSecurity
@Configuration
@ComponentScan({"com.myapp.webapp.config"})
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/account/**").hasRole("USER")
.and()
.formLogin()
.loginPage("/login").permitAll()
.loginProcessingUrl("/login")
.usernameParameter("mail")
.passwordParameter("password")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler())
.invalidateHttpSession(true)
.deleteCookies("mail", "password", "id")
.and()
.rememberMe()
.rememberMeParameter("remember-me");
//.
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
}
SecurityWebApplicationInitializer.class
:
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
}
WebConfig.class
:
@EnableWebMvc
@Configuration
@ComponentScan({"com.myapp.service.config",
"com.myapp.webapp"
} )
public class WebConfig implements WebMvcConfigurer {
private static final Logger logger = LoggerFactory.getLogger(AccountController.class);
@Autowired
EntityManagerFactory emf;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(accountInterceptor()).addPathPatterns("/account", "/editAccount", "/editSecurity", "/editMainInfo");
registry.addWebRequestInterceptor(entityManagerInViewInterceptor()).addPathPatterns("/*");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources ").addResourceLocations("/resources/");
registry.addResourceHandler("/WEB-INF/jsp ").addResourceLocations("/jsp/");
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver=new CommonsMultipartResolver();
resolver.setDefaultEncoding("utf-8");
return resolver;
}
@Bean
public UserDetailsService userDetailsService() {
return new UserDetailsServiceImpl();
}
@Bean
public UserValidationInterceptor accountInterceptor() {
return new UserValidationInterceptor();
}
@Bean
public OpenEntityManagerInViewInterceptor entityManagerInViewInterceptor() {
OpenEntityManagerInViewInterceptor openEntityManagerInViewInterceptor = new OpenEntityManagerInViewInterceptor();
openEntityManagerInViewInterceptor.setEntityManagerFactory(emf);
return openEntityManagerInViewInterceptor;
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
和AppInit.class
:
public class AppInit extends AbstractAnnotationConfigDispatcherServletInitializer{
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{
WebConfig.class,
SecurityConfig.class
};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{
WebConfig.class
};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
在Maven
trowing exception中安装和部署项目后:
10-Jan-2018 18:54:33.562 SEVERE [localhost-startStop-8] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/webapp-1.0-SNAPSHOT]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:952)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1823)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through method 'setContentNegotationStrategy' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mvcContentNegotiationManager' defined in org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.accept.ContentNegotiationManager]: Factory method 'mvcContentNegotiationManager' threw exception; nested exception is java.lang.AbstractMethodError: com.myapp.webapp.config.WebConfig$$EnhancerBySpringCGLIB$$b5f5a3c0.configureContentNegotiation(Lorg/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer;)V
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:667)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at com.myapp.webapp.config.WebServletConfiguration.onStartup(WebServletConfiguration.java:28)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 10 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mvcContentNegotiationManager' defined in org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.accept.ContentNegotiationManager]: Factory method 'mvcContentNegotiationManager' threw exception; nested exception is java.lang.AbstractMethodError: com.myapp.webapp.config.WebConfig$$EnhancerBySpringCGLIB$$b5f5a3c0.configureContentNegotiation(Lorg/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer;)V
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:659)
... 26 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.accept.ContentNegotiationManager]: Factory method 'mvcContentNegotiationManager' threw exception; nested exception is java.lang.AbstractMethodError: com.myapp.webapp.config.WebConfig$$EnhancerBySpringCGLIB$$b5f5a3c0.configureContentNegotiation(Lorg/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer;)V
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
... 38 more
Caused by: java.lang.AbstractMethodError: com.myapp.webapp.config.WebConfig$$EnhancerBySpringCGLIB$$b5f5a3c0.configureContentNegotiation(Lorg/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer;)V
at org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite.configureContentNegotiation(WebMvcConfigurerComposite.java:59)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration.configureContentNegotiation(DelegatingWebMvcConfiguration.java:62)
at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.mvcContentNegotiationManager(WebMvcConfigurationSupport.java:368)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$3318d161.CGLIB$mvcContentNegotiationManager$25(<generated>)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$3318d161$$FastClassBySpringCGLIB$$3906aa77.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$3318d161.mvcContentNegotiationManager(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 39 more
答案 0 :(得分:1)
1.在Spring基础项目中,最好将配置类导入到扩展WebMvcConfigurerAdapter
或webmvcconfigurationsupport
的WebConfig类。
2.在ServletInitializer类中,将webConfig类作为根就足够了 配置类。
public class AppInit extends AbstractAnnotationConfigDispatcherServletInitializer{
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{
WebConfig.class
};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{
};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
在此之前,您必须将安全配置类导入到webApp配置类。
@Import({SecurityConfig.class/*,and other config classes*/})
@EnableWebMvc
@Configuration
@ComponentScan({"com.myapp.service.config",
"com.myapp.webapp"
} )
public class WebConfig implements WebMvcConfigurer {
//other bean stuff
}