인프런 커뮤니티 질문&답변

홍성민님의 프로필 이미지
홍성민

작성한 질문수

호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)

시큐리티 Permission Evaluator

Permission targetId null

작성

·

351

1

  • 당연히 구글링 해보셨져? 원하는 결과를 못찾으셨나요? 어떤 검색어를 입력했는지 알려주세


    >> hasPermission targetId null

  • 문제가 발생한 코드(프로젝트)를 Github에 올리시고 링크를 알려주세요.
    https://github.com/IE-MangChi/RepositoryForAsk.git

  • KakaoTalk_20240109_221729453.png영상에선 그냥 넘어갔지만 targetId값이 null로 찍히는게 맞는지 잘모르겠습니다.
    KakaoTalk_20240109_221652441.png강의내용대로면 저값이 매핑되어야하는데, 공식홈페이지보니 아닌거 같아서 질문드립니다!

답변 2

0

hasPermission에서 targetId 가 null로 받는 현상 관련,

3.2부터 달라진 PathVariable 에 대한 처리 때문인 것 같은데요,

 

hasPermission 을 보면 targetId 는 Serializable (static 이거나 long ) 을 요구합니다.

문제는 PathVariable 이 3.2 부터 key-value 방식을 이용하는데 이게 결국 hash 사용한다는 말이라면 동적 파라미터로 되는 것 같았어요, static 은 아닐 거라 생각드네요..

따라서 #someId 로 hasPermission에 파라미터를 전달할 때, Long type이나 static 이 아닌 key (hash) 값이 넘어갈 수도 있지 않나 생각이 듭니다.

 

우회방안은 여러가지가 있을 것 같은데

저는 authentication 에서 principal 을 받아올 수 있는데 여기에 pk 넣어두고 사용했습니다.

 

  쉽게 말해서 #someId  를 Serializable 로 캐스팅하지 못하는 게 이슈 인 것같아 보이긴 합니다..

0

호돌맨님의 프로필 이미지
호돌맨
지식공유자

님! 제가 잠깐 밖이라 그런데

저 expression호출하는 컨트롤러 코드도 올려주시면 감사하겠습니다.

홍성민님의 프로필 이미지
홍성민
질문자

@Slf4j
@RestController
@RequiredArgsConstructor
public class PostController {

    private final PostService postService;

    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @PostMapping("/posts")
    public Long post(@AuthenticationPrincipal UserPrincipal userPrincipal, @RequestBody @Valid PostCreate postCreate) {
        return postService.write(userPrincipal.getUserId(), postCreate);
    }

    @GetMapping("/posts/{postId}")
    public Post get(@PathVariable("postId") Long postId) {
        return postService.findById(postId);
    }

    @GetMapping("/posts")
    public List<Post> posts(@ModelAttribute("postSearch") PostSearch postSearch) {
        return postService.findAll(postSearch);
    }

    @PreAuthorize("hasRole('ROLE_ADMIN') && hasPermission(#postId, 'POST', 'DELETE')")
    @PatchMapping("/posts/{postId}")
    public void edit(@PathVariable("postId") Long postId, @RequestBody @Valid PostEdit postEdit) {
        postService.edit(postId, postEdit);
    }

    @PreAuthorize("hasRole('ROLE_ADMIN') && hasPermission(#postId, 'POST', 'DELETE')")
    @DeleteMapping("/posts/{postId}")
    public void delete(@PathVariable("postId") Long postId) {
        postService.delete(postId);
    }
}

PostController 전체입니당

 저는 MyBatis를 사용해보아서 postService 메서드 이름은 다릅니다!
수정 메서드에 Permission으로 DELETE를 넘겻는데 오타입니다!

홍성민님의 프로필 이미지
홍성민
질문자

스프링부트 3.2부터는 @Pathvarible @RequestParam 등 name값을 명시하게 바뀌고 권장하는 방식이라 자바 컴파일시 -parameter 옵션을 안주고 저렇게 하였는데,

 

부트 버전을 2.x로 낮추거나, 자바 컴파일 -parameter옵션을 주고
@PreAuthorize(value = "hasRole('ROLE_ADMIN') && hasPermission(#postId, 'POST', 'DELETE')")

@DeleteMapping("/posts/{postId}")

public void delete(@PathVariable Long postId) {

postService.delete(postId);

}
위와같이 name값을 제거해주니 targetId에 잘 넘어오네요.

 

부트3.2 부터 -parameter 옵션을 안주었을 때 매핑이 안되는 이유는 제가 더 찾아보겠습니다.!

감사합니다! 남은 강의도 완강하겠습니다!

홍성민님의 프로필 이미지
홍성민

작성한 질문수

질문하기