2016-03-01 121 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執行。

相關問題