Dailelog

PermissionEvaluator์™€ ๊ถŒํ•œ ์ธ๊ฐ€์ฒ˜๋ฆฌ,@PreAuthorize ๋Œ€ํ•ด ๋ณธ๋ฌธ

JAVA/JAVA SPRING

PermissionEvaluator์™€ ๊ถŒํ•œ ์ธ๊ฐ€์ฒ˜๋ฆฌ,@PreAuthorize ๋Œ€ํ•ด

Daile 2024. 6. 28. 02:47

์„œ๋ก 

<aside> ๐Ÿ’ก Controller์—์„œ ์ธ๊ฐ€์ฒ˜๋ฆฌํ•˜๋Š” ๋ถ€๋ถ„์„ ๊ณต๋ถ€ํ•˜๋ฉด์„œ @Secured(),@PreAuthorize, @PostAuthorize 3๊ฐœ์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด์„œ ์ธ๊ฐ€์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ๋ฉด ๋˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์ด๋ฒˆ์— @PreAuthorize์— ๋Œ€ํ•ด์„œ ์ง‘์ค‘ํ•ด์„œ ์ด์•ผ๊ธฐ ํ•ด๋ณผ ์ƒ๊ฐ์ด๋‹ค.

</aside>

@PreAuthorize

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

์œ„ ์ฝ”๋“œ๋Š” ์ž์‹ ์ด ์ž‘์„ฑํ•œ ๊ฒŒ์‹œ๊ธ€์„ ์‚ญ์ œํ•˜๋Š” ๊ธฐ๋Šฅ์—์„œ post ์— ์ž‘์„ฑ์ž ์ •๋ณด์™€ ์‚ญ์ œ ์š”์ฒญ ์ •๋ณด์— ์œ ์ €์ •๋ณด์˜ ๊ถŒํ•œ์„ ํ™•์ธํ•˜๊ณ  ์ธ๊ฐ€์ฒ˜๋ฆฌ๋ฅผ ์š”์ฒญํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

• @PreAuthorize: ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— ์ธ์ฆ์„ ๊ฑฐ์นœ๋‹ค.

Secured ์• ๋…ธํ…Œ์ด์…˜๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ํ•จ์ˆ˜๋ฅผ String ํ˜•ํƒœ๋กœ ๋„ฃ์–ด์ค„ ์ˆ˜ ์žˆ๊ณ , and๋‚˜ or ๋“ฑ ๋…ผ๋ฆฌ ์—ฐ์‚ฐ์ž๋„ ๋„ฃ์–ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

์• ๋…ธํ…Œ์ด์…˜ ๋‚ด์—์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ํ•จ์ˆ˜/๊ธฐ๋Šฅ๋“ค

  • hasRole([role]) : ํ˜„์žฌ ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ์ด ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ๊ถŒํ•œ๊ณผ ๋™์ผํ•œ ๊ฒฝ์šฐ true
  • hasAnyRole([role1,role2 ...]) : ํ˜„์žฌ ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์˜ ๊ถŒํ•œ ์ค‘ ์ผ์น˜ํ•˜๋Š” ๊ฒƒ์ด ์žˆ๋Š” ๊ฒฝ์šฐ true
  • principal: ์‚ฌ์šฉ์ž๋ฅผ ์ฆ๋ช…ํ•˜๋Š” ์ฃผ์š”๊ฐ์ฒด(User)๋ฅผ ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.
  • authentication : SecurityContext์— ์žˆ๋Š” authentication ๊ฐ์ฒด์— ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • permitAll : ๋ชจ๋“  ์ ‘๊ทผ ํ—ˆ์šฉ
  • denyAll : ๋ชจ๋“  ์ ‘๊ทผ ๋น„ํ—ˆ์šฉ
  • isAnonymous() : ํ˜„์žฌ ์‚ฌ์šฉ์ž๊ฐ€ ์ต๋ช…(๋น„๋กœ๊ทธ์ธ)์ธ ์ƒํƒœ์ธ ๊ฒฝ์šฐ true
  • isRememberMe() : ํ˜„์žฌ ์‚ฌ์šฉ์ž๊ฐ€ RememberMe ์‚ฌ์šฉ์ž๋ผ๋ฉด true
  • isAuthenticated() : ํ˜„์žฌ ์‚ฌ์šฉ์ž๊ฐ€ ์ต๋ช…์ด ์•„๋‹ˆ๋ผ๋ฉด (๋กœ๊ทธ์ธ ์ƒํƒœ๋ผ๋ฉด) true
  • isFullyAuthenticated() : ํ˜„์žฌ ์‚ฌ์šฉ์ž๊ฐ€ ์ต๋ช…์ด๊ฑฐ๋‚˜ RememberMe ์‚ฌ์šฉ์ž๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด true

hasPermission

hasPermission์€ permission ๊ถŒํ•œ์„ ํ™•์ธํ•˜๋Š” ์—ญํ™œ์„ ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋กœ PermissionEvaluator ์ด๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”์„œ๋“œ์ด๋‹ค.

์•„๋ž˜์˜ ์ฝ”๋“œ๋Š” PermissionEvaluator์˜ ์ฝ”๋“œ์ด๋‹ค.

public interface PermissionEvaluator extends AopInfrastructureBean {
    boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission);

    boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission);
}

์œ„์— PermissionEvaluator์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ณ„๋„์˜ ๊ตฌํ˜„์ฒด๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

PermissionEvaluator ๊ตฌํ˜„์ฒด

@Slf4j
@RequiredArgsConstructor
public class DailelogPermissionEvaluator implements PermissionEvaluator {

    private final PostRepository postRepository;
    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        return false;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        var principal = (UserPrincipal) authentication.getPrincipal();

        Post post = postRepository.findById((Long) targetId).orElseThrow(PostNotFound::new);

        if(!post.getUserId().equals(principal.getUserId())){
            log.error("[์ธ๊ฐ€ ์‹คํŒจ] ํ•ด๋‹น ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ•œ ๊ธ€์ด ์•„๋‹™๋‹ˆ๋‹ค. targetId = {}",targetId);
            return false;
        }
        return true;
    }
}

๊ฐ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ด์šฉํ•ด์„œ ์ธ์ฆ๊ฐ์ฒด์—์„œ Principal๋ฅผ ๊ฐ€์ ธ์™€ ๋‚˜์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ๋งž๋Š” UserPrincipal๋กœ ๊ฐ€์ ธ์™€์„œ

targetId๋ฅผ ํ†ตํ•ด ํƒ€๊ฒŸ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋‚ด๋ถ€์— ์ž‘์„ฑ์ž ์•„์ด๋””์™€ UserPrincipal์˜ ์•„์ด๋””๋ฅผ ๋น„๊ต ํ›„ ๊ทธ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ์ธ๊ฐ€ ์Šน์ธ ๊ฒฐ๊ณผ๋ฅผ boolean์œผ๋กœ ๋Œ๋ ค์ค€๋‹ค.

LIST