我正在尝试将Spring安全性与自定义登录页面和对数据库的访问权限添加到我的Spring MVC应用程序中.看起来我的映射是错误的,因为它无法映射j_spring_security_check.
为了解决这个问题,我看了下面的页面1,2,3,但还没有解决问题.
如果您没有太多时间,请阅读下面的第2部分,即问题的编辑部分开始的地方.否则,请阅读第1部分和第2部分.
第1部分
我还在我的web.xml文件中添加了以下行,但应用程序返回以下异常.
Failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:188)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1123)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:302)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:732)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.startup.Catalina.start(Catalina.java:691)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:456)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.apache.catalina.LifecycleException: A child container Failed during start
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1131)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:800)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 6 more
Jun 13,2015 2:44:54 PM org.apache.catalina.startup.Catalina start
SEVERE: The required Server component Failed to start so Tomcat is unable to start.
org.apache.catalina.LifecycleException: Failed to start component [StandardServer[8005]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
at org.apache.catalina.startup.Catalina.start(Catalina.java:691)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:456)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardService[Catalina]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:732)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 7 more
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 9 more
Caused by: org.apache.catalina.LifecycleException: A child container Failed during start
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1131)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:302)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 11 more
在提交表单后不添加该过滤器,请求将由以下控制器捕获.
@Controller
public class MainController {
@RequestMapping("/{viewName}")
public String index(@PathVariable String viewName) {
...
}
web.xml中
我-security.xml文件
AppConfig.java
@EnableWebMvc
@Configuration
@ComponentScan({ "com.myproject.*" })
@EnableTransactionManagement
@Import({ SecurityConfig.class })
public class AppConfig {
@Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(
dataSource());
builder.scanPackages("com.myproject.model").addProperties(
getHibernateProperties());
return builder.buildSessionFactory();
}
private Properties getHibernateProperties() {
Properties prop = new Properties();
prop.put("hibernate.format_sql","true");
prop.put("hiberate.show_sql","true");
prop.put("hibernate.dialect","org.hibernate.dialect.MySQL5Dialect");
return prop;
}
@Bean(name = "dataSource")
public BasicDataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/test");
ds.setUsername("jack");
ds.setPassword("jack");
return ds;
}
@Bean
public HibernateTransactionManager txManager() {
return new HibernateTransactionManager(sessionFactory());
}
}
SecurityConfig.java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(
passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/profile/**")
.access("hasRole('ADMIN')").and().formLogin()
.loginPage("/signin").failureUrl("/signin?error")
.usernameParameter("username").passwordParameter("password")
.and().logout().logoutSuccessUrl("/index").and().csrf().and()
.exceptionHandling().accessDeniedPage("/403");
}
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
SpringMVCInitializer.java
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpringMvcInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
@Override
protected Class>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
LoginController.java
@Controller
public class LoginController {
@RequestMapping(value = "/login",method = RequestMethod.GET)
public ModelAndView login(
@RequestParam(value = "error",required = false) String error,@RequestParam(value = "logout",required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error","Invalid username and password!");
}
if (logout != null) {
model.addObject("msg","You've been logged out successfully.");
}
model.setViewName("login");
return model;
}
}
**
第2部分
根据Thomas的建议,我将代码更改为以下内容
**
web.xml中
AppConfig.java
@EnableWebMvc
@Configuration
@ComponentScan({ "com.myproject" })
@EnableTransactionManagement
@Import({ SecurityConfig.class })
public class AppConfig {
@Bean
public SessionFactory sessionFactory() {
LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(
dataSource());
builder.scanPackages("com.myproject.model").addProperties(
getHibernateProperties());
return builder.buildSessionFactory();
}
private Properties getHibernateProperties() {
Properties prop = new Properties();
prop.put("hibernate.format_sql","org.hibernate.dialect.MySQL5Dialect");
return prop;
}
@Bean(name = "dataSource")
public BasicDataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/test");
ds.setUsername("jack");
ds.setPassword("jack");
return ds;
}
@Bean
public HibernateTransactionManager txManager() {
return new HibernateTransactionManager(sessionFactory());
}
}
SecurityConfig.java
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
// auth.userDetailsService(userDetailsService).passwordEncoder(
// passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/profile/**")
.access("hasRole('ADMIN')").and().formLogin()
.loginPage("/login").failureUrl("/login?error")
.and().logout().logoutSuccessUrl("/index").and().csrf().and()
.exceptionHandling().accessDeniedPage("/403");
}
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
SpringMVCInitializer.java
public class SpringMvcInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
@Override
protected Class>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
MainController
@Controller
public class MainController {
@RequestMapping("/{viewName}")
public String index(@PathVariable String viewName) {
System.err.println("View Name is :" + viewName);
if (isValidView(viewName)) {
return viewName;
}
return null;
}
关于MainController,这是我处理静态页面的方式,例如www.myproject.com/index,www.myproject.com/contactus等.关于这个问题的另一个问题是here
最佳答案
我强烈建议您遵循Java或XML配置.我个人更喜欢Java配置.
原文链接:https://www.f2er.com/spring/432286.html>删除所有与Spring Security相关的XML配置并创建以下内容
文件.
>修改您拥有的许可地址.
public class MessageSecurityWebApplicationInitializer extends
AbstractSecurityWebApplicationInitializer { //register the springSecurityFilterChain with the war
}
public class MessageWebApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class>[] getRootConfigClasses() {
return new Class[] { SecurityConfig.class }; //make sure your config file gets loaded
}
@Override
protected Class>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return null;
}
@Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return null;
}
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
System.err.println("in here");
auth.inMemoryAuthentication().withUser("user@yahoo.com")
.password("password").roles("USER"); //access to inmemory credentials
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resources/**","/","/index","/aboutus")
.permitAll() //allow access to your static pages and resources
.antMatchers("/profile/**")
.hasRole("USER") //profile address is only available to users ( do not need to add ROLE_ as Spring does it for you)
.and() //and is equivalent of end tag in XML
.formLogin().loginPage("/signin").failureUrl("/signin?error")
.permitAll().and().logout().logoutUrl("/singout").permitAll();
}
有关进一步说明和访问DB,请参阅documentation