Spring-framework: Controller throws 404 for all endpoints when implementing interface and adding @Secured to method

Created on 1 Oct 2019  路  5Comments  路  Source: spring-projects/spring-framework

See sample code in branch (feature/secured-interface-bug) to reproduce issue:
https://github.com/caspianb/SpringBootTest/tree/feature/secured-interface-bug

I reproduced this issue in Spring Boot 2.1.0, 2.1.4, and 2.1.8.

Spring Controllers seem to be getting confused when implementing an interface and adding @Secured to an @Override method:

@RestController
public class UserController implements BaseController {

    @Override
    @RequestMapping(method = RequestMethod.GET)
    public ResponseEntity<String> getData() {
        return ResponseEntity.ok("You have access! <a href=\"/api\">Protected Access?</a> | <a href=\"/logout\">Logout</a>");
    }

    @Override
    @Secured("ROLE_ADMIN")
    @RequestMapping(path = "api", method = RequestMethod.GET)
    public ResponseEntity<String> getProtectedData() {
        return ResponseEntity.ok("You have protected access! <a href=\"/logout\">Logout</a>");
    }
}

The above example will always throw a 404 on either endpoint. Simply removing either the @Secured annotation or the implements BaseController will eliminate the 404.

The same occurs if I define the mappings on the interface itself. Ideally, I would like to define the mappings on the interface and then explicitly mark @Secured on implementing classes, but it seems odd that simply implementing an interface in conjunction with @Secured breaks the entire controller.

Note that trying to utilize either @RolesAllowed or@PreAuthorize has the same outcome as @Secured as described above.

web declined

Most helpful comment

I think this is due to proxying. The use of @Secured and @EnableGlobalMethodSecurity combined with implementing an interface is resulting in a JDK proxy being created for UserController. Such proxies lose the request mapping annotations. @EnableGlobalMethodSecurity(proxyTargetClass=true) should avoid the problem.

@caspianb You can learn more in Framework's reference documentation.

All 5 comments

This looks like it's either a Spring Security bug or an issue in Spring Framework. I'll transfer the issue to Spring Framework to see if they've seen it before.

I think this is due to proxying. The use of @Secured and @EnableGlobalMethodSecurity combined with implementing an interface is resulting in a JDK proxy being created for UserController. Such proxies lose the request mapping annotations. @EnableGlobalMethodSecurity(proxyTargetClass=true) should avoid the problem.

@caspianb You can learn more in Framework's reference documentation.

Thanks for the analysis, @wilkinsona.

@caspianb, please try out Andy's recommendation to use @EnableGlobalMethodSecurity(proxyTargetClass = true) and let us know if that resolves the issue for you.

Yup, forcing Spring to utilize the CGLIB proxies does resolve the 404 issue; thank you!

Thanks for confirming that it works!

FYI: I also improved the documentation by providing a Java config example.

I'll close this issue.

Was this page helpful?
0 / 5 - 0 ratings