简体   繁体   中英

SpringMVC (Security) - 403 error

I'm developing a simple Java web application with SpringMVC. With security enabled, I cannot send a HTTP post request (from the index.jsp) to the server although I am already authenticated. POST request does work when the security isn't implemented. So I think it's a problem with my SecurityConfig.java code.Could you please help me with this? Thanks very much

Error Code:

HTTP Status 403 – Forbidden

Type Status Report

Message Forbidden

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

This is my security configuration.

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>

Add http.csrf().disable(); to configure method.

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

}

You are confusing jsp with thymleaf . Edit the jsp file to:

<%@ 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>

The UserDetailService bean that you have provided didn't work for me. I had to change it like this:

@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;
}

When we enable web security, for every form submitted, we need to send the _crsf(cross-site request forgery) token which is generated randomly base on the user's session.

If we don't want to use this token, we can disable it by calling .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();

      }

But, in the real world, the token is preferred for security purposes. There are 2 approaches to generate the token.

  • Approach 1: Generating token automatically by form tag <form:form> . Spring MVC will help us generated the token behind the scenes. use taglib:
     <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

and modify <form action='@{/index}' method="POST"> to:

     <form:form action='@{/index}' method="POST">
          // our html code
     </form:form>
  • Approach 2: Generating token manually by adding the hidden field. Before the close form tag </form> , add the following code.
     <form action='@{/index}' method="POST">
          // our html code 
          ...
          <input type="hidden" name="_csrf.parameterName" value="_csrf.token" />
     </form>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM