【问题标题】:SpringMVC (Security) - 403 errorSpringMVC(安全)- 403 错误
【发布时间】:2018-12-10 01:17:37
【问题描述】:

我正在使用 SpringMVC 开发一个简单的 Java Web 应用程序。启用安全性后,尽管我已经通过身份验证,但我无法向服务器发送 HTTP 发布请求(来自 index.jsp)。未实施安全性时,POST 请求确实有效。所以我认为这是我的SecurityConfig.java 代码的问题。你能帮我解决这个问题吗?非常感谢

错误代码:

HTTP Status 403 – Forbidden

Type Status Report

Message Forbidden

Description The server understood the request but refuses to authorize it.

这是我的安全配置。

SecurityConfig.java

 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.http.HttpMethod;
 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;

 @Configuration
 @EnableWebSecurity
 public class SecurityConfig extends WebSecurityConfigurerAdapter {

     @Autowired
     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().withUser("user1").password("{noop}123456").roles("USER");

        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {

            http
                    .formLogin()
                    .and()
                    .authorizeRequests()
                    .antMatchers("/index").hasRole("USER")
                    .antMatchers(HttpMethod.POST, "/index").hasRole("USER");

        }
    }

index.jsp

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Registration</title>
</head>
<body>

     <form action='@{/index}' method="POST">
     <div class="form-group">

     <td><textarea class="form-control" name="textForm">${text1}</textarea>   
     <input type="submit" value="Submit">
     <textarea name="textFin">${textFinal}</textarea></td>
     </form>
    </div>


</body>
</html>

【问题讨论】:

    标签: java spring-mvc spring-security


    【解决方案1】:

    当我们启用网络安全时,对于每一个提交的表单,我们都需要发送 _crsf(cross-site request forgery) 令牌,该令牌是根据用户的会话随机生成的。

    如果我们不想使用这个令牌,我们可以通过调用.csrf().disable()来禁用它

          @Override
          protected void configure(HttpSecurity http) throws Exception {
    
                http
             .formLogin()
             .and()
             .authorizeRequests()
             .antMatchers("/index").hasRole("USER")
             .antMatchers(HttpMethod.POST, "/index").hasRole("USER")
             .and()
             .csrf().disable();
    
          }
    

    但是,在现实世界中,出于安全目的,令牌是首选。生成令牌的方法有两种。

    • 方法一:通过表单标签&lt;form:form&gt;自动生成token。 Spring MVC 将帮助我们在幕后生成令牌。 使用标签库:
         <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
    

    并将&lt;form action='@{/index}' method="POST"&gt;修改为:

         <form:form action='@{/index}' method="POST">
              // our html code
         </form:form>
    
    • 方法 2:通过添加隐藏字段手动生成令牌。 在关闭表单标签&lt;/form&gt;之前,添加以下代码。
         <form action='@{/index}' method="POST">
              // our html code 
              ...
              <input type="hidden" name="_csrf.parameterName" value="_csrf.token" />
         </form>
    

    【讨论】:

      【解决方案2】:

      添加 http.csrf().disable(); 配置方法。

      protected void configure(HttpSecurity http) throws Exception {
       http
                  .formLogin()
                  .and()
                  .authorizeRequests()
                  .antMatchers("/index").hasRole("USER")
                  .antMatchers(HttpMethod.POST, "/index").hasRole("USER")
                  .and()
                  .csrf().disable();
      
      }
      

      您将jspthymleaf 混淆了。将jsp file 编辑为:

      <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
      <%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
      <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
          "http://www.w3.org/TR/html4/loose.dtd">
      <html>
      <head>
      <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Registration</title>
      </head>
      <body>
      
           <form:form action="/index" method="POST">
           <div class="form-group">
      
           <td><textarea class="form-control" name="textForm">${text1}</textarea>   
           <input type="submit" value="Submit">
           <textarea name="textFin">${textFinal}</textarea></td>
           </form:form>
          </div>
      
      
      </body>
      </html>
      

      您提供的UserDetailService bean 对我不起作用。我不得不像这样改变它:

      @Bean
      public UserDetailsService userDetailsService() {
          // ensure the passwords are encoded properly
          @SuppressWarnings("deprecation")
          UserBuilder users = User.withDefaultPasswordEncoder();
          InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
          manager.createUser(users.username("me").password("me").roles("USER").build());
          return manager;
      }
      

      【讨论】:

      • 您好,感谢您的回复。抱歉耽搁了。我通过添加http..csrf().disable(); 使代码正常工作
      • 您能否将其添加到您的回复中。所以我可以将其标记为正确答案?
      • 非常感谢您的回复和解决我对 jsp 页面的困惑,并告诉我另一种验证用户的方法。
      猜你喜欢
      • 2013-10-28
      • 1970-01-01
      • 2017-09-09
      • 2017-09-19
      • 1970-01-01
      • 2020-01-17
      • 1970-01-01
      • 1970-01-01
      • 2021-02-15
      相关资源
      最近更新 更多