이번 강의에서는
Java 메소드 위에
메소드 레벨 보안을 사용하여
인가를 강제하는 방법을
이해해보겠습니다
이를 위해
우리는 두 가지 주석을 사용해 줍니다
첫번째는 @PreAuthorize
두번째는 @PostAuthorize 주석입니다
첫번째로 사용할 주석은
@PreAuthorize 주석입니다
해당 주석을 사용하여
권한에 관한 규칙 또는
보안에 관한 요구 사항을 정의할 때
Spring Security 프레임워크는
유저 정보에 따른 보안 관련 요구사항이
충족 되어야지만
해당 메소드가 호출되도록 합니다
여기 보시다시피
@PreAuthorized 주석을 사용하기
위한 다양한 접근을 언급해놨습니다
getLoanDetails라는 Java 메소드가 있습니다
해당 메서드는 유저 이름을 input으로 받고
유저 이름을 기반으로
특정 유저의
대출 정보를 로딩하고
동일한 정보를 UI 애플리케이션으로 다시 돌려보냅니다
하지만 이 Java 메소드를
꽤 단순하고 쉽게 만드는 대신
몇가지 권한 규칙을 강제할 수 있습니다
예를 들어 로그인한 유저가
어떠한 권한과 역할을 갖고 있는지
체크하기 위해
@PreAuthorize 주석 속에 hasAuthority, hasRole 메소드를 사용할 수 있습니다
유사하게 hasAnyRole과
hasAnyAuthority도 사용할 수 있습니다
hasAuthority와 hasRole 관련 메소드를
활용하는 것 이외에도
보안 요구사항을 정의 하기 위해
SpEL도 사용할 수 있습니다
따라서 이는
@Secured과 @Role과 같은 주석들을
단독으로 사용하는 것과 비교했을 때
@PreAuthorize @PostAuthorize 주석들이
주는 장점이라고 할 수 있겠습니다
여기에 있는 마지막 구성은
SpEL의 도움을 받아 만들어졌음을 확인할 수 있습니다
이 SpEL로
ID인
입력 매개변수를 가지고
로그인된 ID와
이 메소드로 받은
input의 ID가
동일한지 확인하는 것입니다
어떤 것이 로그인된 ID인지 알 수 있을까요?
바로 Spring Security의 도움을 받아
Spring Security 내에 어떤
인증 객체가 사용 가능한지 확인하는 것입니다
이 인증 객체 속에는
프린시펄(principal)이 있고 이를 기반으로
username을 호출할 수 있습니다
로그인된 유저의 username을 알게된 뒤
이를 메소드를 통해 받은 username
입력 매개변수와 비교합니다
둘이 다르다면
누가 다른 사람의 대출 정보를
열람하려는 시도이기 때문에
실행이 되지 않아야 합니다
그들은 다른 유저의 대출 정보를 얻기 위해
해킹하는 것일 수도
있기 때문입니다
따라서 이러한 상황에서
우리는 메소드 레벨 보안으로 일을 쉽게 처리할 수 있습니다
아주 유사하게는
@PostAuthorize라는
다른 주석이 있습니다
@PreAuthorized 주석과는 다르게
@PostAuthorization 주석은
메소드의 호출을 멈추지 않습니다
대신 Java 메소드의 호출이
별도 권한 규칙 없이 실행되도록 합니다
하지만 @PostAuthorize 주석을 쓸 때마다
어떤 것들이 돌려보내지고 있는지
검증되도록 합니다
@PostAuthorized 주석의 도움으로
리턴 객체가
특정 유저와 연관이 있는지
확인할 수 있습니다
Loan 객체 안에
username 필드가 이있을 수 있습니다
따라서 returnObject.username을
이용하여 로그인된 유저의 username과 동일한지 확인하고
이는 authentication.principal.username의 도움으로 가능합니다
비슷하게
@PreAuthoriz와 같이 @PostAuthorize 안에서도
hasAnyRole, hasAnyAuthority
hasAuthority, hasRole과
같은 메소드들을 사용할 수 있습니다
하지만 말했다시피
@PostAuthorization은 메소드의 실행을 멈추지는 않습니다
오히려 실행을 완료하게 하고
실행이 완료된 후에
정의해둔 권한 규칙을 기반으로
output을 유저에게 다시
돌려보내야 하는지 결정합니다
지금까지 논의한
hasAuthority, hasRole, SpEL등의
모든 접근 방법들로도
보안 요구 사항이나
권한 요구 사항이
달성되지 않는 경우가 있을 수 있습니다
요구 사항들이 아주 복잡하면
언제든지
PermissionEvaluate라는 인터페이스를 오버라이드할 수 있습니다
클래스를 직접 정의하고
PermissionEvaluator 인터페이스를 구현할 수 있습니다
이 PermissionEvaluator 인터페이스를 구현하고 나면
이 인터페이스는 hasPermission과 같이 메소드 이름을 갖게 되고
복잡한 로직은 거기 안에 작성하면 됩니다
그리고 이 hasPermission으로부터
true 혹은 false의 Boolean (불리언) 값을 리턴할 수 있으며
그에 따라 Spring Security는
메소드 호출을 허용이 되는지 안되는지 이해할 수 있습니다
그리고 PermissionEvaluator 구현 클래스 안에
작성한
비즈니스 로직을 전부 호출하기 위해서는
hasPermission 키워드를
@PreAuthorize 또는 PostAuthorize 주석으로 보내야합니다
프레임워크 안에서 해당 인터페이스도
빠르게 확인할 수 있습니다
여기 Spring Security 프레임워크 내에
사용 가능한 PermissionEvaluator
인터페이스를 열었습니다
이 PermissionEvaluator를 구현할 때마다
hasPermissionr과 같이 오버로딩된 메소드들은
오버라이드할 수 있습니다
따라서 이 메소드는 몇가지 입력 매개변수를 받게 될 것입니다
로그인된 유저에 대한 정보를 예로 들 수 있습니다
두번째 매개변수는
targetDomainObject입니다
여기서는 엔드 유저에게
리턴하려는 객체
혹은 엔드 유저에게서 받는 객체와 같은
객체들을 보낼 수 있습니다
따라서 해당 타겟 객체는 두번째 매개변수로 보낼 수 있습니다
세번째 매개변수는 PermissionExpression입니다
이는 hasPermission 메소드 내에서 평가하고 싶습니다
비슷하게
다른 로딩된 메소드도 있는데
targeType이라는 것을 받습니다
타겟하려는 클래스의 이름을 예를 들 수 있습니다
그럼 targetID는 무엇일까요?
여기에는 객체의 ID 또는 직렬화 ID를
언급해야 하는데
직렬화 ID와 타겟 종류를
언급하기 보다는
targetDomainObject의 도움으로
객체 자체를 보낼 수 있습니다
따라서 이는 오버라이딩의 두 가지 방법이었습니다
true, false와 같이 해당 메소드에서
무엇을 리턴하는지를 기반으로
@PostAuthorization과 @PreAuthorization이 일어납니다
hasPermission 메소드 안으로 리턴한
로직을 호출하기 위해서는
언제든지 hasPermission을
@PreAuthorize 혹은 @PostAuthorize과 같은 주석에게 보내면 됩니다
이제 여기서 언제
@PreAuthorize와
@PostAuthorize를 사용할 수 있는지에 대한 질문이 많으실겁니다
제가 추천 드리는 바는 @PostAuthorize의 경우
엔드 유저에게 다시 보내려 하는
작성한 객체를 기반으로
평가를 하고 싶을 때 사용하는 것입니다
하지만 요구 사항이 꽤나 명확하여
예를 들어 권한 관련 규칙들이 충족되지 않을 경우
메소드 호출 자체를 허용하지 않아야할 때
@PreAuthorize 주석을 사용할 수 있습니다
대부분의 상황에서는
@PreAuthorize 주석을 사용하는 경우를 많이 보실겁니다
@PostAuthorize 주석을
필요로하는 상황이 많지 않기 때문이죠
마지막으로 나누고 싶은 정보는
이 마법이 어떻게 일어나는지에 대한 것입니다
예를 들어 주석만 언급했을 뿐인데
Spring Security 프레임워크가
어떻게 보안을 전부 그렇게 실행하는 것일까요?
정답은 Spring AOP입니다.
Spring AOP를 활용하여
런타임에서 Spring Security 프레임워크가
메소드의 호출을
메소드 호출 이전에 인터셉트하여
@PreAuthorized 주석의
도움으로 구성한
모든 권한 보유 관련 규칙을 실행할 수 있는 것입니다
그리고 @PostAuthorize 주석이
있는 경우에는
메소드 출력이 닿기 직전에
Spring Security 프레임워크에서
Spring AOP 이론의 도움으로
메소드 호출을 인터셉트합니다
마법은 Spring 프로젝트 속에서
늘 일어나고 있습니다
내부적으로 그들이
Spring AOP 이론을 활용하고 있음을 확인할 수 있습니다
Spring AOP는 아주 재밌고 강렬한 이론입니다
해당 내용을 모르시면
저의 Spring 교육에서 이를 자세히 다뤘으니
이를 수강하시는 걸 추천 드립니다
웹 애플리케이션에서 메소드 레벨 보안을 실행하는 내용이
명확히 전달되었으면
좋겠습니다
다음 수업 때는
이 내용을 가지고 웹 애플리케이션 속에
권한과 메소드 레벨 보안을 구현해보도록 하겠습니다
그럼 다음 강의에서 뵙겠습니다
감사합니다