【问题标题】:How to fix Forbidden 403 error caused by SpringSecurity?如何修复由 SpringSecurity 引起的 Forbidden 403 错误?
【发布时间】: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");
}

}

【问题讨论】:

    标签: spring-boot jsp spring-security


    【解决方案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 被禁止。
      猜你喜欢
      • 2020-08-16
      • 2020-05-24
      • 1970-01-01
      • 1970-01-01
      • 2020-07-05
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 2021-08-26
      相关资源
      最近更新 更多