티스토리 뷰

Spring Security를 사용할 때 권한 체크를 간단히 할 수 있는 방법은 URL 방식과 Method 방식이 있다

Method 방식은 AOP 방식을 기반으로 한다

특히 @EnableGlobalMethodSecurity 설정을 활성화해 아주 간단히 이용할 수 있다

해당 애너테이션을 찾아가 보면 활성화할 수 있는 요소들을 확인할 수 있다

Role만 지정해주는 간단한 사용을 위해서는 securedEnabled = true로 주면 되고

권한 검증에 SpEL을 사용하려면 prePostEnabled = true로 주면 된다

 

 

모든 설정은 default false이기 때문에 나는 간단한 방식과 SpEL을 사용하는 방식을 혼용하기 위해 두 설정을 켜줬다

아래와 같이 사용하고자 하는 설정을 켜주고 SecurityConfig에 @Enable-- 애너테이션을 붙여주면 된다

나는 SecurityConfig에 Cors, OAuth2, Web, Jwt까지 적용했더니 너무 비대해져

당장에는 프로젝트를 진행하고 있어 파악이 가능하지만 추후 읽는 사람이 이해하기 힘들고,

유지보수에 어려움을 겪을 것 같아 역할 분담을 해 나눠둔 상태이다

 

 

 

핵심으로 돌아가서 나는 권한 검증 외에도 본인여부를 판단하는 기능을 추가하고 싶었다

회원 권한을 가지고 있고 본인일 때, 혹은 관리자일때 실행해야 할 때 사용하는 기능 and, or로 이어주면 된다

본인 여부를 판단하는 @checker.isSelf() method

 

'@PreAuthorize custom method' 키워드로 아래 사이트를 찾았고 훑어봤는데 나한텐 과한 기능이기도 했고

GlobalMethodSecurityConfiguration를 상속하는 MethodSecurityConfig를 만들었을 때 

OAuth2 설정과 부딪혀 적용되지 않아 방법을 찾아봤다 두 번째 링크 블로그 글 마지막 부분에서 해답을 찾았는데 간단하게

Custom class를 Component로 만들던지 method만 bean으로 만들던지 선택해서 직접 검증을 하면 된다

Component로 만든 경우 SpEL 상에서 @클래스.메서드() 형태로 사용하면 된다

@PreAuthorize("@checker.isSelf(#id) or hasRole('ROLE_ADMIN')")

- https://www.baeldung.com/spring-security-create-new-custom-security-expression

- https://stackoverflow.com/questions/6632982/how-to-create-custom-methods-for-use-in-spring-security-expression-language-anno?rq=1

 

 

 

Long 타입의 id를 받아서 회원을 조회한 후 email을 꺼내서 authentication이 가지고 있는 username과 비교하는 메서드다

나는 id를 회원의 primary key로 쓰고 있기 때문에 숫자형이고, email로 웹사이트에서의 아이디 같은 역할을 수행하고 있다

email 역시 unique 제약조건을 둬서 본인여부를 판단할 수 있게 해 놨다

 

User principal = (User) authentication.getPrincipal();

로직을 간단하게 하기 위해 코드에서 User 부분을 UserPrincipal이라는 custom class를 만들고 id 필드도 추가했다

CustomUserDetailsService도 만들어 loadByUsername 수행 시 id를 넘겨주어 UserPrincipal을 생성했었다

 

 

UserPrincipal을 이용하면 isSelf() 메서드를 수행할 때 memberRepository로 네트워크를 타서

조회할 필요가 없으니 성능 향상을 노린 것인데 결과적으로는 적용하지 않게 됐다 

현재 나는 TokenProvider 클래스를 이용해 토큰을 생성하는데

UsernamePasswordFilter 앞에 위치하는 JwtFilter가 TokenProvider에 의존하는 상태다

TokenProvider는 아무것에도 의존하고 있지 않은 상태로 token에서

authentication을 뽑아내는 메서드에서는 UserPrincipal을 생성, 

UsernamePasswordAuthenticationToken에 담아서 반환해줘야 한다

따라서 TokenProvider에서 member의 id를 담은 UserPrincipal 형태를 반환하려면

memberRepository로의 의존이 생기고 모든 요청마다 네트워크를 타고 회원의 id를 조회하게 된다

차라리 본인 여부를 확인해야 하는 메서드에서만 회원 id를 조회하는 게 나으니 현재로서는 최선의 선택을 해봤다

댓글
링크
글 보관함
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Total
Today
Yesterday