代码之家  ›  专栏  ›  技术社区  ›  Dev M

如何在Spring Boot中为任何包含匿名用户表单的页面处理会话创建和添加隐藏输入csrf令牌?

  •  0
  • Dev M  · 技术社区  · 6 年前

    我介绍问题:

    当我启动应用程序并输入url“/主页”时。主页显示但不正确(模板组织不好),我收到一个异常 TemplateInputException 。过了一段时间,如果我刷新主页和其他页面,它会恢复正常,但如果我转到“/登录”,然后我注销,这会将我重定向到主页视图,同样的问题会再次出现。

    Stacktrace控制台:

    组织。百里香叶。例外。TemplateInputException:发生错误 模板解析期间(模板:“类路径资源 [模板/home.html]”)。。。

    原因:组织。attoparser。ParseException异常 :处理器执行期间出错 '组织。百里香叶。spring4。加工机SpringActionTagProcessor'(模板: “主页”-第2494行,第10列) 组织。attoparser。马克·帕瑟。parseDocument(MarkupParser.java:393) ~[attoparser-2.0.4.RELEASE.jar:2.0.4.RELEASE]。。。

    原因:组织。百里香叶。例外。TemplateProcessingException模板处理异常 :错误 处理器执行期间 '组织。百里香叶。spring4。加工机SpringActionTagProcessor'(模板: “主页”-第2494行,第10列)

    原因:java。lang.IllegalState例外: 在提交响应后,无法创建会话 组织。阿帕奇。卡特琳娜。连接器。要求doGetSession(请求:2995) ~[tomcat-embed-core-8.5.14.jar:8.5.14]

    。。。

    位于组织。springframework。安全网状物csrf。httpsessionssrftokenrepository。saveToken(httpsessionsrftokenrepository.java:63) ~[spring-security-web-4.2.0.RELEASE.jar:4.2.0.RELEASE] 组织。springframework。安全网状物csrf。LazyCsrfTokenRepository$SaveonAccessSrftoken。savetokenifnecessaved(LazyCsrfTokenRepository.java:176) ~[spring-security-web-4.2.0.RELEASE.jar:4.2.0.RELEASE] 组织。springframework。安全网状物csrf。LazyCsrfTokenRepository$SaveonAccessSrftoken。getToken(LazyCsrfTokenRepository.java:128) ~[spring-security-web-4.2.0.RELEASE.jar:4.2.0.RELEASE] 组织。springframework。安全网状物servlet。支持csrf。CsrfRequestDataValueProcessor。 getExtraHiddenFields (CsrfRequestDataValueProcessor.java:71) ~[spring-security-web-4.2.0.RELEASE.jar:4.2.0.RELEASE]。。。

    代码来源:

    该问题在家庭联系表中。此行中的html: 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>
    

    我认为这是csrf令牌的问题。我试图添加这一行 <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> 在我的表单中,csrf保护默认由Spring Security启用,但它不起作用。

    调用服务以发送邮件的控制器:

    @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 回复  |  直到 4 年前
        1
  •  3
  •   Dev M    6 年前

    这就是如何解决“无法创建会话和CSRF令牌”的问题。

    在spring安全配置类中,我刚刚添加了这一行 .and().csrf().csrfTokenRepository(..) 一切都很顺利。

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