KEYCLOAK - 2.(인가)_개념잡기

킹콩(King Kong)·2025년 4월 26일

KEYCLOAK 사용법

목록 보기
2/4

▶ Keycloak 인가(Authorization)

1. Keycloak 인가 개요

  • Keycloak을 인증(Authentication)을 위한 도구로만 사용할 수도 있지만, 자원에 대한 세밀한 접근제어를 원할 때는 인가(Authorization) 기능까지 사용해야 제어를 할 수 있다.

2. Authorization(인가) 활성화

  • 인가를 적용하기 위해서 먼저 인가를 적용할 Client를 선택한다.
  • Capability config 하위의 Autorization을 ON으로 설정하면 인가 메뉴 활성화 된다.

3. Authorization 용어 정리

  • 인가를 적용하기 위하여 아래 4개의 용어에 대한 이해가 필요하다.

    [ 용어 정리 ]

    1.자원(resource): 사용자가 접근하려는 페이지 또는 URIs
    2.범위(scope) : 자원에 대한 동작 (C/R/U/D)
    3.정책(policy) : ROLE/GROUP/TIME 별로 다른 정책을 정의
    4.권한(permission) : 특정 자원에 어떤 작업을 누구에게 허용 또는 거부 할지에 대한 정의

4. Keycloak의 인가의 제약사항

  • 인가 정책은 Keycloak에서 정의를 하지만 Application(client)에서는 그 정보를 알 수가 없다. 따라서 Keycloak에 인가 정책을 등록했다고 해서 Application이 인가 정책에 따라 동작하지 않는다.

  • 해결 방안 (인가 여부 체크)

    • Application이 Keycloak 인가 정책 대로 동작하기 위해서는 사용자가 Application의 자원에 접근을 시도할 때, Keycloak에 사용자의 권한으로 접근하려는 자원에 대하여 인가여부를 확인하면 된다.
    • 이를 위하여 Keycloak은 Authorization API(Endpoint)를 제공한다.
    • 따라서 Application은 사용자의 접근 요청에 대하여 그 요청을 수행하기 앞서 Keycloak Authorizaiton Endpoint를 호출하고, 결과에 따라 사용자의 요청을 <허가>할지 또는 <거부>할지 여부를 판단하면 된다.

5. 인가 정책 성능이슈

  • 사용자가 매번 요청시마다 Application이 Keycloak의 Authorization Endpoint를 호출하면 Keycloak의 성능 이슈가 발생 할 수 있다.
  • 이를 극복하기 위해서 사용자가 로그인을 할 때마다 1회만 Keycloak을 호출하여 사용자 권한에 따른 자원의 인가 목록을 받아오면 된다. 이 인가 목록을 Request Party Token, RPT라고 한다.
  • Application은 이 목록을 Caching하여 이후 요청에 대하여는 Cache를 먼저 참조하도록 하면 성능 이슈를 해결 할 수 있다.

6. Keycloak 인가의 활용 전략

  • Keycloak의 인가 기능을 기존 Spring Security 처럼 권한(ROLE)만을 통제/제어 할 것인지,
  • 자원(resource)의 C/R/U/D 까지 상세히 통제/제어할 것인지에 대한 활용 전략을 결정할 필요가 있다.

6.1 방안(1) - ROLE만 체크하기

  • Keycloak 인증 후 Keycloak 에 부여된 사용자의 권한을 Spring Security의 Authority 에 넣어주면 기존 Spring Security 적용했을 때 처럼 동작한다.
  • Keycloak 에서는 Role 정책 과 사용자에 대한 Role 맵핑을 실시간으로 해주기만 하면 로그인 시 바로 적용되게 된다.
  • Role만 체크하는 또 하나의 방법은 Keycloak > Authorization > Permission에서 Role base permission 으로 자원과 권한만 맵핑해 주면 앞의 Authority 를 통해 제어했던 것과 같이 사용자의 자원에 대한 접근 통제 및 제어를 수행 할 수 있다.

6.2 방안(2) - resource + scope + policy까지 체크하기

  • Keycloak에서는 자원에 대한 어떤 행위(동작)까지 세밀하게 제어할 수 있다.
  • Keycloak > Authorization > Permission 메뉴에서 Scope base permission 을 선택하고,
  • 자원(resource) vs 범위(scope/action) vs 정책(policy/role)을 맵핑해 주면 된다.
  • 또는 Application은 RPT(Request Party Token) 토큰을 받아서 권한을 체크하면 상세한 부분까지 접근 통제 및 제어가 가능하다.

7. RPT(Request Party Token)

  • RPT는 사용자의 권한에 대해 접근이 허용되는 자원/범위에 대한 목록을 말한다.
  • 아래 Endpoint를 통해 요청하면 발급 받을 수 있고 샘플은 아래와 같다.
    • Endpoint : /protocol/openid-connect/token
    • 자원별로 자원명(rsname), 범위(scope), 자원ID(rsid)이 Object로 리턴된다.
# RPT sample
[
    {
        "rsid": "6d8166dd-fd3d-4a3f-a67a-417adf73af39",
        "rsname": "/admin/*",
        "scopes": [
            "GET",
            "POST",
            "PUT",
            "DELETE"
        ]
    },
    {
        "rsid": "88110074-6c39-47e2-b4ff-002172b655d4",
        "rsname": "/user/*",
        "scopes": [
            "GET",
            "POST",
            "PUT",
            "DELETE"
        ]
    }
]

8. Resource 제어시 이슈

  • RPT 토큰을 활용하여 자원에 대한 접근을 제어 시 이슈가 있다.
  • resource-id vs resource name
    • 자원(resource) 등록시 URIs 정보에 자원의 패턴을 등록한다. (예를 들면 /admin/*, /user/* 처럼 패턴으로 등록)
    • 그러나 Authorization Endpoint를 통해서 RPT 권한 토큰을 받으면 여기에는 URIs 가 없다. 따라서 사용자가 요청한 URI가 허용되는 자원인지 여부를 판단 할 수 가 없다.
  • 해결책 (Work-around)
    • 이를 해결하기 위하여 RPT(권한토큰) 발급시 들어있는 resource name을 활용한다. resource name에 URIs 패턴과 같은 값을 넣어 주고 패턴 비교시 자원명(rsname)의 패턴과 사용자가 요청한 URI를 비교한다.

      [ 이슈 ]

      • RPT 권한토큰에 URIs 패턴 정보가 없음
      • rsname을 차선책으로 활용하여 권한 허가/거부 여부를 판단함

9. Decision strategy

  • 자원과 범위, 정책을 조합하여 권한(permission)을 등록하면 정책 상호간에 충돌이 발생 할 수 있다.
    • 예를 들면, 같은 자원인데 어떤 정책에서는 접근을 허용(Positive/Permit)하고
    • 어떤 정책에서는 접근을 불가(Negative/Deny) 시킬 수 있다.
  • 이를 해결하기 위하여 Keycloak에서는 아래 3가지 전략을 제시한다.

    Affirmative(긍정, 동의)

    • 여러 정책 중에 하나라도 허용이면 전체를 <허용>
    • 가장 관대한 방식

    Unamimouse(만장일치)

    • 모든 정책이 허용이어야 함, 하나라도 불가가 있으면 전체가 <불가>
    • 가장 엄격한 방식

    Consensus(합의)

    • 허용의 개수가 불가보다 많으면 <허용>, 불가의 개수가 허용보다 많으면 <불가>
    • 균형있는 다수결 방식
profile
IT를 쉽게 이해해 보아요~😄

0개의 댓글