使用 Spring Security 时出现意外的 403 错误
Posted
技术标签:
【中文标题】使用 Spring Security 时出现意外的 403 错误【英文标题】:Unexpected 403 error when using Spring Security 【发布时间】:2021-04-05 15:43:54 【问题描述】:这里我有一个表单的 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());
【问题讨论】:
你使用 Spring Security 吗? 是的,我正在使用 Spring Security 所以发布你的@Configuration
课程
看来您保护了提交表单的端点并试图在未经授权的情况下访问它。仅在授权后允许表单或从 SecurityConfig 中删除其路径。
Spring 安全性要求所有的 post 请求默认都有 csrf。添加 csrf 参数(推荐)或禁用 csrf(不推荐)。见this。
【参考方案1】:
正如 @dan1st 在评论部分提到的,在使用 SpringSecurity 时,所有表单提交都需要CSRF
(除非你禁用它)。要在表单中自动添加csrf token
,一种简单的方法是使用百里香标签。一旦 thymeleaf 在表单中检测到其标签,它会在丢失时将 csrf 令牌添加到隐藏输入中。
这是一个例子
<form th:action="@'your_post_path'" method="POST" th:object="$yourModelAttributeEntity">
...
</form>
您可以添加其中一个或两个都添加
【讨论】:
好吧,酷。您可以将答案标记为正确答案,以帮助未来的读者以上是关于使用 Spring Security 时出现意外的 403 错误的主要内容,如果未能解决你的问题,请参考以下文章
Groovy:使用 Grails 和 Spring 安全核心插件时出现意外令牌
使用 CorsFilter 和 spring security 时出现 Cors 错误
使用 Spring Security 实现 LDAP 身份验证时出现 Gradle 依赖关系错误