How to handle session creation and adding hidden input csrf token for any page containing a form for an anonymous user in Spring Boot?

我只是一个虾纸丫 提交于 2021-02-08 09:58:10

问题


I Introduce the problem:

when I launch the application and I enter the url "/home". The home page is displayed but not correctly (the template is not well organized) and I receive an exception TemplateInputException. After a while, If I refresh the home page and the other pages It comes back to normal but if I go to "/login", and I logout which redirects me to the home view the same issue comes back again.

The Stacktrace Console:

org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/home.html]") ...

Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring4.processor.SpringActionTagProcessor' (template: "home" - line 2494, col 10) at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]...

Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring4.processor.SpringActionTagProcessor' (template: "home" - line 2494, col 10)

Caused by: java.lang.IllegalStateException: Cannot create a session after the response has been committed at org.apache.catalina.connector.Request.doGetSession(Request.java:2995) ~[tomcat-embed-core-8.5.14.jar:8.5.14]

...

at org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.saveToken(HttpSessionCsrfTokenRepository.java:63) ~[spring-security-web-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.security.web.csrf.LazyCsrfTokenRepository$SaveOnAccessCsrfToken.saveTokenIfNecessary(LazyCsrfTokenRepository.java:176) ~[spring-security-web-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.security.web.csrf.LazyCsrfTokenRepository$SaveOnAccessCsrfToken.getToken(LazyCsrfTokenRepository.java:128) ~[spring-security-web-4.2.0.RELEASE.jar:4.2.0.RELEASE] at org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor.getExtraHiddenFields(CsrfRequestDataValueProcessor.java:71) ~[spring-security-web-4.2.0.RELEASE.jar:4.2.0.RELEASE] ...

The Code source:

The issue is in the Contact Form of the home.html in this line: th:action="@{/home/contact}" th:object="${mailForm}":

<form id="contact-form" method="post" action="/home/contact}" 
    th:action="@{/home/contact}" th:object="${mailForm}"
    role="form">
    <!-- <input type="hidden" name="${_csrf.parameterName}" 
    value="${_csrf.token}" /> -->
    <input type="text" name="senderName" th:field="*{senderName}"> 
    <input type="text" name="senderLastName" th:field="*{senderLastName}">  
    <input type="email" name="senderEmail" th:field="*{senderEmail}">            
    <textarea name="message" th:field="*{message}"></textarea>
    <button type="submit">Send Message</button>
</form>

I think it's a problem with csrf token. I tried to add this line <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> in my form and the csrf protection is enabled by default by Spring Security but it did not work.

The Controller that calls the service to send mails:

@Controller
public class HomeController {
    @Autowired
    private EmailService emailService;
    @Autowired
    private MailValidator mailValidator;
    
    // some other code like @InitBinder methode ...
    
    // method to post mailForm
    @PostMapping("/home/contact")
    public String contactUsHome(@Valid @ModelAttribute("mailForm") final MailForm mailForm, BindingResult bindingResult)
            throws MessagingException {

        if (bindingResult.hasErrors()) {
            return HOME_VIEW;
        } else {
            mailForm.setRecipientEmail(recipientEmail);
            Mail mail = DTOUtil.map(mailForm, Mail.class);
            emailService.sendSimpleMail(mail);
            return REDIRECT_HOME_VIEW;
        }
    }
}

回答1:


This is how to fix the issue "Cannot create a session and CSRF token".

In the spring security configuration class, I just added this line .and().csrf().csrfTokenRepository(..) and everything works well.

@Override
protected void configure(HttpSecurity http) throws Exception {
     http.authorizeRequests()
     //some another line of code...
     .and().csrf().csrfTokenRepository(new HttpSessionCsrfTokenRepository())
}


来源:https://stackoverflow.com/questions/50199266/how-to-handle-session-creation-and-adding-hidden-input-csrf-token-for-any-page-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!