복붙노트

[SPRING] 스프링 보안 + MVC : 동일한 @RequestMapping, 다른 @Secured

SPRING

스프링 보안 + MVC : 동일한 @RequestMapping, 다른 @Secured

Spring MVC와 스프링 보안을 사용하여 API 엔드 포인트를 설정했다고합시다. 유일한 @Secured 주석 값이 쌍마다 다른 @RequestMapping과 @Secured 주석의 쌍을 처리 할 수 ​​있기를 원합니다. 이렇게하면 동일한 요청에 대한 보안 규칙에 따라 다른 응답 본문을 반환 할 수 있습니다.

이렇게하면 메소드 본문에 직접 보안 규칙을 확인하지 않아도 코드를 유지 관리 할 수 ​​있습니다.

작동하지 않는 예제를 사용하면 다음과 같이 할 수 있습니다.

@Controller
@RequestMapping("/api")
public class Controller {

    @Secured ({"ROLE_A"})
    @RequestMapping(value="{uid}", method=RequestMethod.GET)
    @ResponseBody
    public Response getSomething(@PathVariable("uid") String uid) {
        // Returns something for users having ROLE_A
    }

    @Secured ({"ROLE_B"})
    @RequestMapping(value="{uid}", method=RequestMethod.GET)
    @ResponseBody
    public Response getSomethingDifferent(@PathVariable("uid") String uid) {
        // Returns something different for users having ROLE_B
    }
}

우리는 어떻게 이것을 할 수 있습니까? 그리고 이것이 가능한 경우 : ROLE_A와 ROLE_B를 모두 가진 사용자의 우선 순위는 어떻게 관리되어야합니까?

해결법

  1. ==============================

    1.RequestMappingHandlerMapping (및 RequestMappingHandlerAdapter)과 함께 Spring 3.1 (또는 그 이상)을 사용한다고 가정하면 요청 매핑 메커니즘을 확장 할 수 있습니다. RequestCondition 인터페이스의 독자적인 구현을 작성하고 RequestMappingHandlerMapping을 확장하여 메소드의 @Secured 주석에 기초하여이를 구성 할 수 있습니다.

    RequestMappingHandlerMapping (및 RequestMappingHandlerAdapter)과 함께 Spring 3.1 (또는 그 이상)을 사용한다고 가정하면 요청 매핑 메커니즘을 확장 할 수 있습니다. RequestCondition 인터페이스의 독자적인 구현을 작성하고 RequestMappingHandlerMapping을 확장하여 메소드의 @Secured 주석에 기초하여이를 구성 할 수 있습니다.

    RequestMappingHandlerMapping에서 'getCustomMethodCondition'메소드를 대체하고 Method와 @Secured 주석의 존재를 기반으로 RequestCondition의 사용자 정의 구현을 구성해야합니다. 들어오는 요청을 메소드와 일치시킬 때 모든 정보가 고려됩니다.

    관련 답변 (@Secured 주석에 대해서는 특정하지 않지만 메커니즘은 동일합니다)은 여기 또는 여기에서 찾을 수 있습니다.

  2. ==============================

    2.나는 spring-mvc에서 이것을 할 수 있다고 생각하지 않는다. 왜냐하면 두 경로 모두 정확히 같은 @RequestMapping (@Secured)이 spring-mvc의 라우트 엔진에 고려되지 않기 때문이다. 가장 쉬운 해결책은 이렇게하는 것입니다.

    나는 spring-mvc에서 이것을 할 수 있다고 생각하지 않는다. 왜냐하면 두 경로 모두 정확히 같은 @RequestMapping (@Secured)이 spring-mvc의 라우트 엔진에 고려되지 않기 때문이다. 가장 쉬운 해결책은 이렇게하는 것입니다.

    @Secured ({"ROLE_A", "ROLE_B"})
    @RequestMapping(value="{uid}", method=RequestMethod.GET)
    @ResponseBody
    public Response getSomething(@PathVariable("uid") String uid, Principal p) {
        // Principal p gets injected by spring
        // and you need to cast it to check access roles.
        if (/* p.hasRole("ROLE_A") */) {
            return "responseForA";
        } else if (/* p.hasRole("ROLE_B") */) {
            return "responseForB";
        } else {
            // This is not really needed since @Secured guarantees that you don't get other role.
            return 403;
        }
    }
    

    그러나 응답이 역할마다 다르므로 약간 다른 URL로 2 개의 개별 요청 매핑을 사용하는 것이 좋으므로 디자인을 변경하겠습니까? 어떤 시점에서 동시에 역할 A와 B가있는 사용자가 있다면 사용자가 얻을 응답을 선택할 수 없습니다 (예 : LinkedIn의 공개 프로필과 비공개 프로필을 생각해보십시오)

  3. from https://stackoverflow.com/questions/17995744/spring-security-mvc-same-requestmapping-different-secured by cc-by-sa and MIT license