2016-03-01 76 views
0

我正在构建基于Spring Security Hello World示例的Spring Web应用程序。我试图通过Spring Security实现日志记录。我可以成功登录但无法注销。出现重定向的预期,但在登录页尝试注销后加载:使用Spring Security和CSRF保护登录/注销Spring应用程序

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 

抛出:

Mar 01, 2016 3:24:01 PM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [laughing-robot] in context with 
    path [/laughing-robot] threw exception [An exception occurred processing JSP page /WEB-INF/jsp/login.jsp at line 43. 

Stacktrace:] with root cause 
java.lang.IllegalStateException: Cannot create a session after the response has been committed 
at org.apache.catalina.connector.Request.doGetSession(Request.java:2928) 
at org.apache.catalina.connector.Request.getSession(Request.java:2298) 

这里是JSP中的注销表单:

     <c:url var="logoutUrl" value="/logout"/> 
         <form action="${logoutUrl}" method="post"> 
          <input type="submit" value="Logout" /> 
          <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 
         </form> 

任何人有有什么建议么?我很高兴提供源文件,但不知道什么是相关的。

UPDATE:

我一直在试图通过注释设置此(VS xml配置)。我不确定这样做的优点/缺点。这里是我的servlet.xml

<?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:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 


<mvc:resources mapping="/images/**" location="/images/" /> 
<mvc:annotation-driven /> 
<context:component-scan base-package="com.robot.configuration"/> 
<mvc:default-servlet-handler/> 

<bean name="/" class="com.robot.controllers.HelloController" /> 
</beans> 

我的登录控制器(我不认为实际上正在实施,在这里设置多个断点那些从不打。):

@EnableWebMvc 
@ComponentScan("com.robot.configuration") 
public class LoginController extends WebMvcConfigurerAdapter { 

protected final Log logger = LogFactory.getLog(getClass()); 

@Override 
public void addViewControllers(ViewControllerRegistry registry) { 
    registry.addViewController("/login").setViewName("login"); 
    registry.setOrder(Ordered.HIGHEST_PRECEDENCE); 
} 
} 

我的安全配置类:

@Configuration 
@EnableWebSecurity 
public class RobotSecurityConfig extends WebSecurityConfigurerAdapter { 

@Autowired 
RobotLoginSuccessHandler robotLoginSuccessHandler; 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
    .csrf().disable() 
    .authorizeRequests() 
     .antMatchers("/images/**").permitAll() 
     .anyRequest().authenticated() 
     .antMatchers("/", "/home").access("hasRole('USER')") 
     .antMatchers("/admin/**").access("hasRole('ADMIN')") 
     .and().formLogin().loginPage("/login").successHandler(robotLoginSuccessHandler) 
     .usernameParameter("username").passwordParameter("password") 
     .and().csrf() 
     .and().exceptionHandling().accessDeniedPage("/Access_Denied") 
     .and() 
    .formLogin() 
     .loginPage("/login") 
     .usernameParameter("username") 
     .passwordParameter("password") 
     .permitAll() 
     .and() 
    .logout()          
     .permitAll(); 
} 

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

你可以显示spring-security配置文件吗? – SAP

+0

更新了附加文件的问题。 – JohnQuincyKerbal

+0

默认配置期望您的角色以“ROLE_”开头,除非您更改org.springframework.security.vote.RoleVoter的rolePrefix。尝试添加ROLE_前缀 – SAP

回答

0

结束写了一个实现LogoutSuccessHandler的类。我完全从股票LogoutSuccessHandler中复制方法。然后我修改了SecurityConfiguration类包括注销参数:

protected void configure(HttpSecurity http) throws Exception { 
    http 
    .csrf().disable() 
    .authorizeRequests() 
     .antMatchers("/images/**").permitAll() 
     .anyRequest().authenticated() 
     .antMatchers("/", "/home").access("hasRole('USER')") 
     .antMatchers("/admin/**").access("hasRole('ADMIN')") 
     .and().formLogin().loginPage("/login").successHandler(robotLoginSuccessHandler) 
     .usernameParameter("username").passwordParameter("password") 
     .and().exceptionHandling().accessDeniedPage("/Access_Denied") 
     .and() 
    .formLogin() 
     .loginPage("/login") 
     .usernameParameter("username") 
     .passwordParameter("password") 
     .permitAll() 
     .and() 
    .logout() 
     .and().logout().logoutUrl("/login?logout").addLogoutHandler(robotLogoutSuccessHandler) 
     .permitAll(); 
} 

我想,既然我定义我自己的配置类,我需要指定正是我想要的LogoutHandler执行。

相关问题