본문 바로가기
공부/Open Source

[Keycloak 21/Terraform] AWS SAML 로그인 연동하기

by haejang 2023. 10. 29.
728x90
728x90

# provider 설정

2023.10.29 - [공부/IaC] - [Terraform] Keycloak Provider 구성하기 (Keycloak 21)

 

# 로컬 변수 설정

locals {
  keycloak_url   = "" # keycloak 주소
  keycloak_realm = "" # aws용 keycloak realm 이름
}

 

# [keycloak] aws client 생성

resource "keycloak_saml_client" "aws" {
  realm_id = local.keycloak_realm

  client_id                   = "urn:amazon:webservices"
  idp_initiated_sso_url_name  = "amazon-aws"
  assertion_consumer_post_url = "https://signin.aws.amazon.com/saml"

  full_scope_allowed = false

  sign_documents          = true
  sign_assertions         = true
  include_authn_statement = true

  signature_algorithm = "RSA_SHA256"
  signature_key_name  = "NONE"

  valid_redirect_uris = [
    "https://signin.aws.amazon.com/saml",
  ]
}

 

# [keycloak] client mapper 생성

locals {
  keycloak_aws_client_id = keycloak_saml_client.aws.id
}

resource "keycloak_saml_user_attribute_protocol_mapper" "aws_session_name" {
  realm_id      = local.keycloak_realm
  client_id     = local.keycloak_aws_client_id
  name          = "Session Name"
  friendly_name = "Session Name"

  user_attribute             = "username"
  saml_attribute_name        = "https://aws.amazon.com/SAML/Attributes/RoleSessionName"
  saml_attribute_name_format = "Basic"
}

resource "keycloak_generic_protocol_mapper" "aws_session_duration" {
  realm_id        = local.keycloak_realm
  client_id       = local.keycloak_aws_client_id
  name            = "Session Duration"
  protocol        = "saml"
  protocol_mapper = "saml-hardcode-attribute-mapper"
  config = {
    "attribute.name"       = "https://aws.amazon.com/SAML/Attributes/SessionDuration"
    "attribute.nameformat" = "Basic"
    "attribute.value"      = "28800"
    "friendly.name"        = "Session Duration"
  }
}

resource "keycloak_generic_protocol_mapper" "aws_session_role" {
  realm_id        = local.keycloak_realm
  client_id       = local.keycloak_aws_client_id
  name            = "Session Role"
  protocol        = "saml"
  protocol_mapper = "saml-role-list-mapper"
  config = {
    "attribute.name"       = "https://aws.amazon.com/SAML/Attributes/Role"
    "attribute.nameformat" = "Basic"
    "friendly.name"        = "Session Role"
    "single"               = "true"
  }
}

 

# [aws] keycloak idp 생성

data "http" "this" {
  url = "${local.keycloak_url}/realms/${local.keycloak_realm}/protocol/saml/descriptor"
}

resource "aws_iam_saml_provider" "this" {
  name                   = "keycloak" # 원하는 이름 작성
  saml_metadata_document = data.http.this.response_body
}

 

# [aws] keycloak용 role 생성

locals {
  keycloak_saml_idp = aws_iam_saml_provider.this.arn
}

data "aws_iam_policy_document" "this" {
  statement {
    actions = ["sts:AssumeRoleWithSAML"]
    principals {
      type        = "Federated"
      identifiers = [local.keycloak_saml_idp]
    }

    condition {
      test     = "ForAnyValue:StringEquals"
      variable = "SAML:aud"
      values   = ["https://signin.aws.amazon.com/saml"]
    }
  }
}

resource "aws_iam_role" "this" {
  name               = "" # Role Name 작성
  assume_role_policy = data.aws_iam_policy_document.this.json
}

 

# [keycloak] aws role과 매핑되는 keycloak role 생성

locals {
  role_arn = aws_iam_role.this.arn
}

resource "keycloak_role" "this" {
  realm_id    = local.keycloak_realm
  client_id   = local.keycloak_aws_client_id
  name        = "${local.keycloak_saml_idp},${local.role_arn}"
}

 

# [keycloak] [추가] keycloak group 설정

## Keycloak Group 생성
resource "keycloak_group" "this" {
  realm_id = local.keycloak_realm
  name     = "" # 사용할 Group Name
}

## Default Group 구성
## realm당 1개라, 디폴트로 넣을 그룹들이 있다면 한번에 취합 후 같이 넣어줘야 함
resource "keycloak_default_groups" "this" {
  realm_id = local.keycloak_realm
  group_ids = [
    keycloak_group.this.id
  ]
}

## Group에 Role 부여
## Group : Role 이 1:n임 (AWS처럼 attachment 하나씩이 리소스가 아님)
## -> 그룹에 매핑할 롤들을 한번에 취합 후 같이 넣어줘야 함
resource "keycloak_group_roles" "this" {
  realm_id = local.keycloak_realm
  group_id = keycloak_group.this.id

  role_ids = [
    keycloak_role.this.id
  ]
}

 

물론 실제로는 모듈, 반복 등등이 더 복잡하게 들어가있다.

그러나 그 부분은 사용하는 사람마다 다를 것 같기에 기본 리소스 단위로만 공유한다. 알아서 커스텀하자..

 

끝!

 

 

728x90
728x90

댓글