본문 바로가기
관리자

Programming-[Backend]/Keycloak

Keycloak Scope 설정 방법(Evaluate, mapper, dedicated, full scope allowed)

728x90
반응형

 

1. User Attribute 추가, 토큰에 포함 확인

 

1.1 User Attribute 추가

User Profile에 속성값을 추가하고(nickname), Client Scopes에 추가하여 Realm 내에서의 Scope를 설정할 수 있다. User Profile에서 속성을 추가할 때, Enabled when 값을 default인 Always로 설정하면 아래 내용대로 적용된다.

attribute 생성화면

 

 

1.2 토큰 확인

scope를 생성할 때 Default로 생성하는 경우 access_token 및 id_token에 기본적으로 포함된다. 다만 따로 설정하지 않으면 token endpoint 응답 body의 "scope" 항목에는 보이지 않는다(아래 그림).

 

 

주의할 사항은 로그인하는 사용자의 nickname 값 자체가 설정되어있지 않으면 위 설정과 관계없이 token에 nickname이 포함되지 않는다는 것이다. 값이 없을 때 null 등으로 포함되는 것이 아니라 attribute 자체가 없을 수 있으므로 조회하는 클라이언트 쪽에서 유의해야한다. 디폴트로 attribute의 값을 설정하는 것은 UI상에서는 확인이 힘들다. 게다가 해당 속성 값이 realm 내의 전체 client에서 사용된다는 보장도 없다. 또한 값이 없는데 굳이 payload가 커지는 것을 방지하기 위함으로 이해가 된다. 클라이언트에서 null check을 잘해야한다는 것을 인지해야할 것 같다.

 

1.3 토큰 확인 - Evaluate

위에서는 실제 로그인 후 토큰 값을 파싱하여 추가한 attribute의 포함 여부를 직접 검사했으나, keycloak에서는 굳이 로그인하지 않아도 특정 유저에 대해 토큰이 어떻게 출력될 수 있는지를 알려주는 Evaluate 기능이 있다. 이 기능은 아래 사진처럼 특정 클라이언트의 상세 페이지에서 확인할 수 있다.

 

scope, user를 선택하여 지정할 수 있고, 그 때 우하단의 Generated access/ID token 부분들을 통해서 실제 토큰에 어떤 값들이 포함되는지를 평가할 수 있게 된다.

 

 

2. 설정에 따른 토큰에서의 노출 여부

기본적으로 client를 생성 후 로그인을 시도하면 openid, email, profile scope가 포함된다. 이는 Client 상세 -> Client Scopes의 Assigned client Scope에서 조정할 수 있다.

 

특히, profile scope는 Realm Settings에서의 User Profile 값의 포함 여부를 결정한다. profile scope는 default로 처리되어 있으므로 해당 scope가 포함되면 커스텀으로 생성한 attribute가 추가되고, 값이 존재하는 경우 토큰에 무조건 포함되게 된다.

 

2.1 먼저 알아두어야할 점

2.1.1 scope 설정 단위

아래 계층별 설정에서도 다루지만, keycloak에서의 scope 설정 단위는 3가지가 있다.

 

1. realm 단위

Realm 화면에서 Client scopes 메뉴에 들어갔을 때 설정할 수 있는 scope 단위이다. 여기서 Realm 전체에 대한 scope를 설정해줄 수 있다. 그리고 여기서 설정해야만 이 다음 단계인 client별 세부 scope 설정이 가능해진다.

 

2. Client 상세 화면 단위

위 1번 단계에서 realm 단위의 scope를 설정했다면, 특정 client 상세화면(아래 그림에서는 test-app)에서 add client scope를 눌렀을 때 팝업이 뜨면서 scope를 추가할 수 있게 된다.

 

그리고 이에 따른 우선순위는 아래 계층별 설정 절에서 참고하면 된다.

 

3. dedicated 설정

Client 상세 설정에서만 scope를 설정할 수 있는게 아니라, dedicated 설정에서도 커스텀한 scope를 client용 scope로 설정할 수 있다. {client명}-dedicated 라는 항목으로 들어가서, 아래 그림처럼 mapper를 설정해주면 된다.

 

User Attribute 타입으로 추가하면 사용자 속성으로 추가되어 토큰에 포함된다. 다시 말해 profile scope가 포함되는 경우 이 항목도 자동으로 포함된다. Configure a new mapper 또는 By Configuration 버튼 -> User Attribute 타입 형태로 추가하면 아래처럼 추가할 수 있다.

 

2.1.2 client 상세 vs dedicated 차이점

dedicated는 전용이라는 뜻이다. client 상세나, dedicated나 둘 다 특정 클라이언트를 위한 scope 설정인데 어떤 차이가 있을까?

  • dedicated 에서 설정하면 위 realm 설정 후에 client 상세에서 설정해야하는 제약이 없다. 바로 dedicated 내부 화면에서 mapper를 통해 scope를 지정해주면 된다.
  • dedicated 설정은 권한 설정도 가능하다. 아래 그림처럼 scope 탭에 들어가서 role를 부여해주면 특정 role을 갖는 경우에만 해당 scope가 부여되도록 할 수 있다. 부가적으로 기본 내용이지만, client를 생성하고나면 Full scope allowed는 OFF 처리해주는 것이 권장된다. 설정한 스코프 외에는 자동으로 토큰에 포함되지 않도록 관리하는 것이 보안상 좋기 때문이다.

 

 

 

2.2 계층별 설정

scope에 profile이 포함되지 않은 상황이라면, 아래 표의 열의 왼쪽부터 낮은 우선순위로 적용된다. 왼쪽 열부터 오른쪽 열으로 갈수록 상세한 단위이다(realm -> client -> scope 단위).  keycloak의 나머지 설정들과 마찬가지로 상세한 단위의 설정이 더 우선시 된다(7, 8번 항목 비교 참고). 설정별 토큰 노출 여부를 살펴본다.

순번 User profile -
Enabled When
Client Scopes -
Assgined type
Client Detail -
client scope
scope
파라미터 추가 여부
토큰 노출 여부
(Access Token)
설명
1 Always 없음(설정하지 않음) 없음 X X Assigned Type, client scope 설정이 없으면 토큰에 포함되지 않음
2 상동 Default/Optional/None 없음 X X 상동
3 Scopes are requested
- scope를 설정하지 않음
Default/Optional/None 없음 X X 상동
4 Scopes are requested
- scope 설정
None Optional X, O X Mapper 설정이 없으면 토큰에 포함되지 않음
5 상동 None
-Mapper: User Attribute type으로 추가
상동 X X scope 파라미터가 없으면 포함되지 않음
6 상동 상동 상동 O O Mapper 설정 및 scope 설정 시 토큰에 포함
7 상동 상동 Default X O Default로 설정 시 scope 여부와 상관없이 토큰에 포함
8 상동 Default, Mapper 설정 Optional X X 상위 Assigned Type에서 Default 처리했더라도, 하위 client scope에서 Optional 처리했다면 적용 X

 

 

5번 항목의 Assigned types의 mapper 설정은 아래 그림처럼 한다.

 

 

3. Scope 설정과 토큰에 포함되는 권한(role) 관리

 

3.1 full scope allowed가 ON 상태일 때

하나의 realm에 test-app, test-app2 라는 2개의 클라이언트가 있고 각각 test-role, test-role2라는 role이 생성되어있다고 하자. 그리고 realm 내부에 이 2개의 role을 갖는 사용자가 account-console client로 로그인 했을 때 access token의 내용을 확인해본다. 아래 그림처럼 해당 유저에 role만 부여하고 account-console의 설정은 따로 변경하지 않아서 full scope allowed는 ON되어있는 상태일 때를 가정한다.

 

 

access_token에 담기는 정보 중 일부를 확인해보면, realm_access 부분에 realm에 관한 권한 정보가, resource_access 부분에 각 client에 대한 권한 정보가 포함되어있는 것을 볼 수 있다.

 

resource_access 부분에 test-app, test-app2의 권한 정보가 모두 포함되어있는 것은 account-console에서 full scope allowed가 켜져있기 때문이다. 이것은 account-console client로 접근했을 때, test-app, test-app2에 대한 모든 권한을 확인할 수 있다는 의미가 된다. 또한 given_name, family_name 등 개별 scope를 설정해야 보이는 모든 속성들도 보이게 된다고 보면 된다.

 

3.2 full scope allowed가 OFF 일 때

 full scope allowed 설정을 OFF 하면 다른 client들에 대한 권한 정보는 미포함된다. 아래 토큰 내용에는 나오지 않지만, 인증을 시도하는 client 자체의 role들은 기본적으로 포함이 된다. 다른 client의 role에 대한 포함 여부를 관리하기 위해서는 dedicated 화면에 들어가서 scope 관리를 해줘야한다. 예를 들어 account-console에서 full scope allowed 설정을 끄면 access_token에 포함된 정보는 아래와 같이 확인된다.

 

만약 account_console에 로그인 했을 때, test-app의 test-role도 포함시켜서 보고 싶다면, account_console의 dedicated 화면에서 해당 항목을 scope로 설정해줘야한다.

 

이후 access_token을 확인해보면 test-app에 대한 test-role이 포함된 것을 확인할 수 있다.

 

3.3 최소 권한 원칙(Principle of Least Privilege)

위 3.1, 3.2 절에서 살펴본 것처럼 full scope allowed를 꺼두면 client마다 어떤 client에 대한 role이 포함되어야하는지를 설정해야하므로 불편할 수 있다. 그러나 이는 보안의 기본 원칙인 '최소 권한 원칙(Principle of Least Privilege)'를 지키기 위함이다.

 

시스템 또는 사용자에게 필요한 최소한의 권한을 부여해야한다.

 

관리의 대상이 될 수 있겠으나, 관리하지 않으면 해당 client에서 알아야만 하는 정보 뿐 아니라 다른 모든 정보까지 token으로 전달될 수 있고 이는 클라이언트가 의도하지 않은 민감 정보에 접근할 수 있는 가능성을 열어두는 결과로 이어진다. 그리고 클라이언트가 탈취될 경우 악의적으로 사용될 여지를 남겨두게 되는 것이기 때문에 scope를 관리해주는 것이 맞다.

 

keycloak에서는 특정 client에 대한 role을 검색하고 필터링할 수 있게 해두었으므로, 기준 client1 에서 client2에 대한 모든 권한이 필요하다면 아래처럼 필터링하여 전체 선택 후 부여만 해주면 된다. 그다지 번거로운 작업은 아니다.

728x90
반응형