如何修复由 SpringSecurity 引起的 Forbidden 403 错误?
Posted
技术标签:
【中文标题】如何修复由 SpringSecurity 引起的 Forbidden 403 错误?【英文标题】:How to fix Forbidden 403 error caused by SpringSecurity? 【发布时间】:2019-09-22 01:59:24 【问题描述】:我正在运行 Spring Boot 应用程序,但无法从 html 表单中请求参数。每当我尝试使用 POST 方法通过表单发送参数时,它都会引发 Forbidden 403 错误。即使我将 spring 安全设置更改为 anyRequest.permitAll,它仍然会抛出 403。知道如何解决这个问题吗?
mastermind_home.jsp:
<form action="/mastermind/home" method="POST">
<label>
<input type="radio" name="difficulty" value="easy">
</label>Easy<br>
<label>
<input type="radio" name="difficulty" value="medium" checked>
</label>Medium<br>
<label>
<input type="radio" name="difficulty" value="hard">
</label>Hard<br>
<input type="submit" value="Start game">
</form>`
控制器:
@AllArgsConstructor
@Controller
@RequestMapping("mastermind")
public class MastermindController
private MastermindServiceImpl mastermindService;
private UserService userService;
@GetMapping("/home")
public String prepareMmHomePage()
return "mastermind_home";
@PostMapping("/home")
public String formRequest( @RequestParam String difficulty)
return "mastermind_home";
Spring 安全设置:
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
private DataSource dataSource;
public SecurityConfiguration(DataSource dataSource)
this.dataSource = dataSource;
@Bean
public PasswordEncoder passwordEncoder()
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
@Bean
public Authentication authentication()
return SecurityContextHolder.getContext().getAuthentication();
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder())
.usersByUsernameQuery("SELECT user_name, password, true FROM users WHERE user_name = ?")
.authoritiesByUsernameQuery("SELECT user_name, 'ROLE_USER' FROM users WHERE user_name = ?");
@Override
public void configure(WebSecurity web) throws Exception
super.configure(web);
@Override
protected void configure(HttpSecurity http) throws Exception
http.authorizeRequests()
.antMatchers("/main_menu","/mastermind/**").authenticated()
.antMatchers("/admin", "/admin/**").hasRole("ADMIN")
.antMatchers("/home", "/register", "/registered_successfully").anonymous()
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/main_menu")
.and()
.logout()
.logoutSuccessUrl("/home");
【问题讨论】:
【参考方案1】:在 spring 安全配置中禁用 csrf 解决了我的问题。
and()
.csrf().disable();
我的问题的另一个更好的解决方案:在 spring security 我添加了:
.antMatchers(HttpMethod.POST, "/mastermind/home").authenticated()
并在 jsp 中形成一个验证 csrf 的令牌:
<input type="hidden" name="$_csrf.parameterName" value="$_csrf.token" />
【讨论】:
【参考方案2】:将此添加到 spring security 以忽略 url 模式
@Override
public void configure(WebSecurity webSecurity) throws Exception
webSecurity.ignoring()
// All of Spring Security will ignore the requests.
.antMatchers("/mastermind/home");
@Override
protected void configure(HttpSecurity http) throws Exception
..........
【讨论】:
使用你的方法我可以 POST 参数并且我没有得到任何异常,但现在我无法从会话中获取用户... 给出的配置完全忽略了 Spring Security 的 url 模式,所以如果你需要会话没有会话,那么这个解决方案将不起作用【参考方案3】:在您的 Spring 安全配置中,您指定所有对以 /mastermind
开头的 URL 的请求都需要经过身份验证 (.antMatchers("/main_menu","/mastermind/**").authenticated()
)。
如果您想为POST /mastermind/home
设置一个例外,那么您需要将您的配置更改为如下所示
http.authorizeRequests()
.antMatchers(HttpMethod.POST, "/mastermind/home").permitAll()
.antMatchers("/main_menu","/mastermind/**").authenticated()
....
请注意这两行的顺序很重要,因为 Spring 以相同的顺序匹配请求 URL。
【讨论】:
这个解决方案对我不起作用。仍然 403 被禁止。以上是关于如何修复由 SpringSecurity 引起的 Forbidden 403 错误?的主要内容,如果未能解决你的问题,请参考以下文章
如何修复由 Pycharm 中的 Tensorflow 引起的 cudart64_110.dll 错误?
如何修复由数据类型关系引起的“变量“$_v0_data”得到无效值' - Mutation Resolver
如何修复由 react-redux 中的循环依赖引起的“不变违规”
如何修复由目的地引起的膨胀错误不是此 NavGraph 的直接子级
如何修复由 Caused by: java.lang.NumberFormatException: For input string: "pets" 引起的 Asynctask 错