-1

As far as Spring security is concerned, it is completely new to me. I found many sources online describing how to set up basic security and was able to get HTTPS REST calls to work with the following configuration on the server side:

@Configuration
@EnableWebSecurity
@EnableConfigurationProperties(SecurityAuthProperties.class)
public class ServerSecurityConfiguration extends WebSecurityConfigurerAdapter {

  private final SecurityAuthProperties properties;

  @Autowired
  public ServerSecurityConfiguration(SecurityAuthProperties properties) {
    this.properties = properties;
  }

  @Override
  public void configure(HttpSecurity http) throws Exception {
    properties.getEndpoints().forEach((key, value) -> {
      try {
        for (HttpMethod method : value.getMethods()) {
          http.authorizeRequests().antMatchers(method, value.getPath()).permitAll().and()
              .httpBasic().and().csrf().disable();
        }
      } catch (Exception e) {
        throw new SecurityConfigurationException(
            "Problem encountered while setting up endpoint restrictions", e);
      }
    });

    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  }

}

Upon closer inspection, though, it looks as though some portion (not sure how much) is actually being disabled. Could this be why it allows access from a client?

When I modified the configuration to what follows below, I always get the response "Forbidden".

  @Override
  public void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/rst/**").permitAll();
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  }

It seems to me that this code would allow access to anything in the path /rst and under, yet the opposite seems to be true. What am I missing?

Note: Another thing I should mention is that there is currently no "user" authentication. The "client" is not web based, but is a separate Spring Boot service that has its own client-side security configuration.

Update:

Here is one of the controllers:

@RestController
@RequestMapping("/rst/missionPlanning")
public class MissionPlannerController {

  @Autowired
  private MissionPlanner         service;
  @Autowired
  private ThreadPoolTaskExecutor executor;

  @PostMapping(value = "/planMission", produces = MediaType.APPLICATION_JSON_VALUE)
  public DeferredResult<ResponseEntity<GeneralResponse>> planMission() {
    DeferredResult<ResponseEntity<GeneralResponse>> result = new DeferredResult<>(60000L);
    executor.execute(new Runner(result));
    return result;
  }

  private class Runner implements ITask {

    private DeferredResult<ResponseEntity<GeneralResponse>> result;

    public Runner(DeferredResult<ResponseEntity<GeneralResponse>> result) {
      this.result = result;
    }

    @Override
    public void executeTask() {
      // Invoke service and set result.
      result.setResult(ResponseEntity.ok(service.planMission()));
    }
  }
}

Update:

Interesting. I found an example from another SO post (Security configuration with Spring-boot) that seems to work. The only thing that's different is the disabling of CSRF.

I see that stands for Cross-Site Request Forgery, but I don't really understand what that is, whether I should have it enabled, and if I do, how do I get it to work then?

  @Override
  public void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests().antMatchers("/rst/**").permitAll();
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  }
Joseph Gagnon
  • 1,731
  • 3
  • 30
  • 63

1 Answers1

1

There could be something wrong with how you've set up your controller. Does your controller that contains that path have @RequestMapping("/rst")?

It'd be helpful if you updated your post with what your controller looks like.

Edit: It seems your issue was the type of request being made if you had to disble CSRF.

CSRF requires a token to be specified on all request methods that can cause a change (i.e. POST, PUT, DELETE, PATCH, but not GET).

The reason for this is that when you control the web page, it adds a layer of security where only you are allowed to make these API calls. Without the CSRF token specified in the request, a malicious user will not be able to make that request to your service since the CSRF token is impossible to guess.

You can read more about it here: https://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/csrf.html#csrf-include-csrf-token

And here: https://www.baeldung.com/spring-security-csrf