이 강의에서는
Spring Security 프레임워크 내에서
권한 정보가 정확히 어디에 저장되는지
이해해보고자 합니다
왜냐하면 내 웹 애플리케이션 내에서
인가를 강제하기 위해서는
우선적으로 Spring Security 프레임워크 내에서
권한 또는 특권 정보를
어떻게 저장하는지를 이해해야 합니다
Spring Security 에서 우리는 이 권한 또는 특권을
두 가지의 용어로 부릅니다
제일 첫 번째는 권한(Authorities)라는 용어 자체이고
두 번째 용어는 역할(Roles)입니다
권한과 역할 사이에는 차이점이 존재합니다
그리고 Spring Security 내에서 우리는 언제 권한을 사용하는지
언제 역할을 사용하는지를 알아야 합니다
그러나 권한과 역할 모두 Spring Security 프레임워크 내에서
저장되는 방식에 있어서는
비슷합니다
우리는 먼저 권한에 대하여 이야기 해보고
이후 역할에 대해 알아볼 때
제가 여러분에게
권한과 역할 사이의
그 차이점이 무엇인지
그리고 언제 권한 또는 역할을 사용하는지에 대해 알려드리겠습니다.
우리의 주된 질문으로 돌아와서
Spring Security 프레임워크 내에서
어느 곳에 권한과 역할이 저장될까요?
부여된 권한이라고 하는 인터페이스가 있습니다
이 인터페이스에서 getter 메소드가 있으며
이 getter 메소드의 구현체는 문자열 입니다
알다시피 Spring Security는 단순히 인터페이스를 정의하는 것에 그치지 않고
항상 구현체를 제공합니다
항상 이러한 인터페이스들의
실행 예시를 보여주어
우리의 웹 애플리케이션 개발에
이를 활용할 수 있습니다
즉 그 말은 부여된 권한의 인터페이스에 대해서도
Spring Security 프레임워크 내에서 구현된 클래스가 있으며
이 클래스의 명칭은
SimpleGrantedAuthority 입니다
이 클래스 내에서는 생성자가 존재합니다
특정 엔드 유저에게
권한 혹은 역할을 배정하고 싶은 사람은
이 SimpleGrantedAuthority 의
생성자를 문자열의 형식으로 역할의 이름과 함께
불러야 합니다
그러면 같은 내용이 SimpleGrantedAuthority의
객체 내부에 저장될 것입니다
어느 한 시점에 언제든 우리의 Spring 프레임워크가
이 엔드 유저의 역할이나 권한이
무엇인지 알아보고 싶다면
SimpleGrantedAuthority 내부의
getAuthority 메소드를 이용할 것입니다
그러니 먼저 이 인터페이스와
Spring Security 내의 클래스들을 검증해 보겠습니다
여기서 볼 수 있듯이
우리는 Spring Security 프레임워크 내에
Interface GrantedAuthority를 보유하고 있습니다
그리고 그 안에는 getAuthority 라는 이름으로
추상 메소드 한 개를 가지고 있습니다
이 인터페이스 SimpleGrantedAuthority라는
클래스가 구현되어 있으며
이는 Spring Security 팀에서 자체적으로 제공한 것입니다
여기를 보면 GrantedAuthority를 구현하고 있고
그 안에
최종 타입의 'role' 이라는 변수를 가지고 있습니다
예를 들어 누군가가 역할 또는 권한을
한 엔드 유저에게 맡기려 한다면
그냥 이 클래스의 생성자를 부르면 됩니다
이 말은 곧 객체가 생기고 역할과 권한이 만들어지고
엔드 유저에게 배정되었다면
그 누구도 그 정보를 변경할 수 없다는 것을 의미합니다
이것이 바로 우리가 이 클래스 내에 setter 메소드를 가지지 않고
get 메소드만 가지는 이유입니다
이 getAuthority 메소드와
우리의 Spring Security 프레임워크를 활용하여
엔드 유저의 역할 또는 권한에 대한 정보를 얻을 것입니다
이렇게 하면 Spring Security가
엔드 유저의 권한 및 역할을 저장할 것입니다
자 이제 여러분은 궁금증이 생길 수도 있습니다
현재는 사용자 상세 서비스와
AuthenticationProvider를 활용하여
직접 로직을 작성함으로서
많은 인증 작업을 수행하고 있습니다
여러분이 다음과 같이 질문할 수도 있을 것 같습니다
이 권한들이 사용자 상세 정보와
인증 인터페이스 내에서
어디에 저장되어 있는 것일까요?
왜냐하면 우리는 인증 중에서
이러한 정보를 많이 활용하고 있는데
유저 상세 인터페이스의 구현 클래스인
유저 클래스 아래에는
데이터베이스에서 로딩한
특정한 사용자의 권한을 가져오기 위해서
Spring Security 프레임워크에 의해 호출되는
getAuthorities 메소드가 있습니다
그러나 마찬가지로 AuthenticationProvider 시나리오에서도
UsernamePasswordAuthenticationToken
객체를 생성할 때
나의 프레임워크는 여전히
인터페이스 내부에 사용 가능한
getAuthorities 메소드를
호출할 것입니다
따라서 이러한 처리 과정이 진행됩니다
또 우리는 프로젝트 내에서도 동일한 내용을 확인할 수 있습니다
IDEA를 확인해 봅시다
먼저 우리가 모든 인증을
작성한 AuthenticationProvider의
구현을 확인해 보겠습니다
우리가 UsernamePasswordAuthenticationToken의 형식으로
인증 객체를 만드는 동안
유저의 이름이 무엇인지
비밀번호는 무엇인지, 권한의 목록은 무엇인지의 정보를 전달합니다
따라서 우리가 이러한 권한의 목록을 전달하려고 할 때
우리는 이 코드를 사용하여 SimpleGrantedAuthority 클래스의 객체를
GrantedAuthority의 형태로 전송하고 있습니다
이 코드에서는 SimpleGrantedAuthority 객체를 생성하고
이 생성자에게는
데이터베이스에서 문자열의 형식으로 가져온
역할 정보를 전달합니다
그리고 마지막으로 이 생성자 내부에서
권한이 이 라인을 실행하여 저장되는 것을
확인할 수 있습니다
이 라인의
super(authorities)를 확인해 보면 알 수 있습니다
자 여기 우리는 모든 권한을
수정되지 않은 리스트로 저장하고 있고 이는 권한이 엔드 유저에게 배정되고 나면
아무도 수정할 수 없음을 의미합니다
또한 언제든 나의 프레임워크가 다음 권한들을 필요로 하면
단순히 이 getAuthorities 메소드를
호출합니다
그리고 언제든 프레임워크가 이 getAuthorities 메소드를
호출할 때면
이 코드 라인이 실행될 것입니다
그리고 나의 프레임워크는 우리가 저장 시스템으로부터 로딩했던
권한의 리스트들을 불러올 것입니다
우리는 섹션 4에서 살펴보았던
유저 상세 서비스 구현을 확인할 수도 있습니다
예를 들어 EasyBankUserDetails를 열어보면
여기서는 데이터베이스에서 유저의 상세 정보를 로드하고
유저 상세 정보 객체를
프레임워크에 전송하는 것 뿐입니다
여기서도 우리는 비슷한 전략을 따라갈 겁니다
이 유저 생성자에 대해 살펴보면
우리는 유저 이름, 비밀번호 및
데이터베이스에서 로드한 권한 목록을
SimpleGrantedAuthority 객체를 생성하여 전달하는 것을 볼 수 있습니다
이 User 클래스를 확인하여도
getAuthorities 라는 메소드가 있는데
이 메소드를 활용하여 나의 프레임워크는
나의 엔드 유저의
권한 또는 역할 정보가 무엇인지를 파악합니다
따라서 여러분이 둘 중 어느 것을 사용하든
나의 프레임워크는 항상 같은 구조를 활용할 겁니다
비록 명칭이 getAuthorities 이지만
이것은 항상 역할을 위해서도 사용될 수 있습니다
Spring Security 프레임워크 안에서
getRoles 같은
다른 메소드는 존재하지 않습니다
지금까지 강의 내용들을 토대로 저는 이제 여러분이
Spring Security 프레임워크 내에서
이러한 권한 또는 역할 정보가 어디에 저장되는 지에 관해 명확히 이해하고
이러한 권한 상세 정보가
프레임워크 내에서 언제든 권한을 수행하려고 할 때
유저 상세 정보 및 인증 인터페이스의 객체에서
어떻게 가져오는지에 대해서도
명확히 알고 계실 것으로 생각합니다
이제 우리는 권한이 어디에 저장되는지에 관해
확실히 이해할 수 있습니다
이제는 한 단계 더 나아가서 이러한 권한을 활용하고
웹 애플리케이션 내에서 일부 인가를 강제해 보도록 하겠습니다
감사합니다 다음 강의에서 뵙겠습니다
수고하셨습니다