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