Spring Boot Duplicated Endpoints

1.1k views Asked by At

The first thing to clarify is that perhaps the title is not very concrete but I do not know how to express it better because I do not understand the problem I have.

A little bit of context: I have a Spring Boot application with JWT authentication and Swagger installed.

The controller I am using as an example has the following content.

@RestController
@RequestMapping("/api/v1")
@CrossOrigin(origins = "*")
@Api(value = "Operations Dummy")
public class DummyController {

    @Autowired
    IDummyService _IDummyService;

    @ApiOperation(value = "Get All Dummy")
    @GetMapping("/dummy")
    public ResponseEntity<ResultList<DummyDTO>> getAllDummy() {
        return _IDummyService.getAll();
    }

}

Like this controller there are several, all similar.

The correct functioning of the application would be to call the endpoint GET http://localhost:8080/api/v1/dummy

The response would be similar to the following:

{
  "data": [
    {
      "id": 0,
      "name": "test"
    },
    {
      "id": 1,
      "name": "dummy"
    }
  ],
  "metadata": {
    "count": 0
  }
}

The problem is that some of the endpoints are accessible from the root, as follows: GET http://localhost:8080/dummy

And they produce a different response, but still show the data

{
  "_embedded" : {
    "dummy" : [ {
      "id" : "0",
      "name" : "test",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080A/dummy/0"
        }
    },{
      "id" : "1",
      "name" : "dummy",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/dummy/1"
        }
    } ]
  },
  "_links" : {
    "first" : {
      "href" : "http://localhost:8080/dummy"
    },
    .
    .
    .
  },
  "page" : {
    "size" : 20,
    "totalElements" : 32,
    "totalPages" : 2,
    "number" : 0
  }
}

For more information this is a copy of the configuration file:

@Override
protected void configure(HttpSecurity http) throws Exception {
    
    http.cors().and().csrf().disable().             
    authorizeRequests()
    .antMatchers("/api/v1/users/auth").permitAll()
    .antMatchers("/error",
            "/v2/api-docs",
            "/configuration/ui",
            "/swagger-resources/**",
            "/configuration/**",
            "/swagger-ui.html",
            "/webjars/**").permitAll()
    .antMatchers("/api/v1/**").authenticated()
    .and()
    .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    
    http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}

As I said, not with every controller this happens, in fact, when I realized that this problem was happening, I deleted the dummy controller and compiled the project again, and it was still possible to get the information through /dummy and not through /api/v1/dummy

As for the logs, when we call /dummy the following log is produced:

o.s.web.servlet.DispatcherServlet        : GET "/dummy", parameters={}
m.m.a.RequestResponseBodyMethodProcessor : Using 'application/hal+json;q=0.8', ...
m.m.a.RequestResponseBodyMethodProcessor : Writing [PagedResource { content: 
o.s.web.servlet.DispatcherServlet        : Completed 200 OK

while for the call to /api/v1/dummy it is:

s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.example.es.controller.DummyController#getAllDummy()
o.s.web.servlet.DispatcherServlet        : GET "/api/v1/dummy", parameters={}
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.example.es.controller.DummyController#getAllDummy()
o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Using 'application/json', given [*/*] and supported [application/json, application/*+json, application/json, application/*+json]
o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Writing [com.example.es.util.ResultList@19771362]
o.s.web.servlet.DispatcherServlet        : Completed 200 OK

Update:

I have added the following line in the application.properties file and it seems that now it does return 404, but I am not sure if this can affect the operation

spring.data.rest.detection-strategy=annotated
1

There are 1 answers

0
wak786 On BEST ANSWER

Since you are using spring-data-rest starter it does a lot of things behind the scenes.

Such as -

  • Exposes a discoverable REST API for your domain model using HAL as media type.

  • Exposes collection, item and association resources representing your model.

Basically all your repositiories and collections are exposed as APIs.

By default, Spring Data REST serves up REST resources at the root URI, '/'. That is why you are able to get response for http://localhost:8080/dummy.

You can this root by setting spring.data.rest.basePath in application.properties.

So if you set it to spring.data.rest.basePath=/pablo then you won't get response data for http://localhost:8080/dummy. Instead you will get response on http://localhost:8080/pablo/dummy

Some useful docs :-

https://docs.spring.io/spring-data/rest/docs/3.3.4.RELEASE/reference/html/#reference