javascript - 使用 Spring Security 时出现意外的 403 错误
问题描述
在这里,我有一个表单的 html 代码。用于创建事件的表单。它要求用户提供一些信息,然后他必须按下按钮 create 。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head th:replace="fragments :: head"></head>
<body class="container">
<nav th:replace="fragments :: header"></nav>
<form method="post">
<div class="form-group">
<label>Name
<input th:field="${event.name}" class="form-control">
</label>
<p class="error" th:errors="${event.name}"></p>
</div>
<div class="form-group">
<label>Description
<input th:field="${event.eventDetails.description}" class="form-control">
</label>
<p class="error" th:errors="${event.eventDetails.description}"></p>
</div>
<div class="form-group">
<label>Contact Email
<input th:field="${event.eventDetails.contactEmail}" class="form-control">
</label>
<p class="error" th:errors="${event.eventDetails.contactEmail}"></p>
</div>
<div class="form-group">
<label>Category
<select th:field="${event.eventCategory}">
<option th:each="eventCategory : ${categories}"
th:value="${eventCategory.id}"
th:text="${eventCategory.name}"
></option>
</select>
<p class="error" th:errors="${event.eventCategory}"></p>
</label>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-success">
</div>
</form>
</body>
</html>
在这里,我有我的表单的 java 代码。
@GetMapping("create")
public String displayCreateEventForm(Model model){
model.addAttribute("title", "Create Event");
model.addAttribute(new Event());
model.addAttribute("categories", eventCategoryRepository.findAll());
return "events/create";
}
@PostMapping("create")
public String processCreateEventForm(@ModelAttribute @Valid Event newEvent, Errors errors, Model model){
if (errors.hasErrors()){
model.addAttribute("title", "Create Event");
return "events/create";
}
eventRepository.save(newEvent);
return "redirect:";
}
我不知道为什么按下按钮后它会给我一个错误,例如:
白标错误页面。此应用程序没有显式映射 /error,因此您将其视为后备。
2020 年 12 月 29 日星期二 00:24:57 EET 出现意外错误(类型=禁止,状态=403)。禁止。
配置类
package com.example.demo.config;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(
"/registration**",
"/js/**",
"/css/**",
"/img/**",
"/webjars/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.permitAll();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
auth.setUserDetailsService(userService);
auth.setPasswordEncoder(passwordEncoder());
return auth;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
}
解决方案
正如@dan1st在评论部分提到的,在CSRF
使用 SpringSecurity 时,所有表单提交都需要它(除非你禁用它)。要在您的表单中自动添加csrf token
,一种简单的方法是使用百里香标签。一旦 thymeleaf 在表单中检测到它的标签,它就会在丢失时将 csrf 令牌添加到隐藏的输入中。
这是一个例子
<form th:action="@{'your_post_path'}" method="POST" th:object="${yourModelAttributeEntity}">
...
</form>
您可以添加其中之一或两者
推荐阅读
- java - 如何在带有 Android 的 Telegram 中与具有 ID 的特定人员共享图片和描述?
- angular - Angular 1 - routeProvider 在 html5Mode 下不工作
- android - 如何仅使 gboard 键盘单词预测可见而不是键 Android Studio
- javascript - 如何访问函数范围之外的变量Angular 9
- javascript - 数字的 HTML 表单验证
- java - 具有拖放功能的 Android Service 类型浮动操作按钮
- flutter - 去除 Flutter 中 Gridview 之间的空格
- javascript - 如何从现场演示中复制和应用代码?
- r - 使用 R networkD3 包中的 forceNetwork 函数显示边缘权重
- email - 如何直接从 Common Lisp 发送电子邮件?