Keycloak이 Active Directory에 등록된 사용자로 인증할 수 있도록 합니다.

사내 시스템을 출시함에 있어서, 전회사에서는 Web시스템마다 로그인하고 있어 혐오가 있었으므로, 꼭 싱글 사인온으로 하고 싶다고 생각했다. 그 실현에, 옛날 조금만 평가한 OpenAM라든지의 정보를 구구어 낚시하기 시작하면, Keycloak의 정보가 눈에 띄었으므로, 새로운 것에 흐르기 쉽기 때문에 Keycloak의 공부를 시작했습니다.
하지만 Keycloak에 모든 직원의 계정 정보를 등록하는 것은 번거롭기 때문에 기존 Active Directory와 협력하는 방법을 시도했습니다.

구성



프로토콜은 본래, HTTPS와 LDAPS이 아니면 안 되지만, 그것은 다음의 단계라고 하는 것으로 안이한 채. Active Directory 서버 LDAP로 정보를 확인하기 위해, 여기 에서 소개되고 있던, Windows Server에 원래의 LDP를 사용했다.

Keycloak 서버



건설



Docker Compose에서, 조금.
version: '3'
services:
  keycloak:
    image: jboss/keycloak
    environment:
      DB_VENDOR: POSTGRES
      DB_ADDR: postgres
      DB_DATABASE: keycloak
      DB_USER: keycloak
      DB_SCHEMA: public
      DB_PASSWORD: password
      KEYCLOAK_USER: admin
      KEYCLOAK_PASSWORD: password
    ports:
      - 50000:8080
  postgres:
    image: postgres
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: password

시험이므로 DB의 영속화를 하고 있지 않습니다.
덧붙여 이때의 keycloak는 6.0.1, PostgreSQL는 11.3이었습니다.

설정


  • Realm 만들기.
  • User Federation을 선택합니다.
  • Add provider...에서 LDAP를 선택합니다.

  • 열린 화면에서 다음 항목을 설정하여 Save.


    품목

    비고


    콘솔 디스플레이 이름
    ${임의의 이름}

    Import Users
    OFF
    ON이라고 Active Directory에서 Keycloak내에 계정 정보를 카피하는 것 같지만, 이번은 인증할 수 있을지 확인할 뿐이므로 OFF.

    편집 모드
    READ_ONLY
    안전을 위해 Keycloak 측에서 실시한 계정 정보의 업데이트가 Active Directory 측에 반영되지 않도록 했다.

    Vendor
    Active Directory

    Username LDAP attribute
    sAMAccountName

    연결 URL
    ldap://${Active Directory 서버 호스트 이름}

    사용자 DN
    ${LDP에서 조사한 사용자가 등록된 DN}

    Bind DN
    ${LDP에서 조사한 자체 계정의 DN}

    Bind Credential
    ${자체 계정 비밀번호}



    ${}는 환경 의존 값입니다.
    Import Users에서,
    편집 모드를 READ_ONLY로 설정하면,
  • 같은 화면의 Mappers 탭을 열고 username을 선택. LDAP Attribute를 sAMAccountName으로 변경합니다.
  • 나머지는 Clients에서 웹 앱용 설정을 등록. Client Protocol은 디폴트의 openid-connect 그대로, Client ID에 sample-keycloak와 Root URL에 웹 앱의 URL을 지정.

  • 웹 앱



    Spring Boot로 작성.

    pom.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.5.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>quo.vaids.megasys</groupId>
        <artifactId>sample-keycloak</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>sample-keycloak</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>11</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.keycloak</groupId>
                <artifactId>keycloak-spring-boot-2-starter</artifactId>
                <version>4.0.0.Final</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    

    application.yml
    keycloak:
      realm: ins.local
      auth-server-url: http://${Keycloakが動いている}:50000/auth
      resource: sample-keycloak
      public-client: true
      security-constraints:
        - securityCollections:
            - patterns:
                - /*
          authRoles:
            - uma_authorization
    

    나머지는 src/main/resources/static에 index.html을 넣었다. 이제 security-constraints에서/
    *를 지정하고 있으므로 웹 앱에 액세스하면 Keycloak로 리디렉션됩니다.

    이때 Active Directory 측에는 역할에 해당하는 정보가 존재하지 않지만 authRoles를 지정하지 않으면 액세스 제한이 걸리지 않기 때문에 고민했다. 하지만, Keycloak측에서 Relm의 디폴트로서 offline_access와 uma_authorization 롤을 할당하고 있는 것을 알아차리고, 이것을 지정했다.

    동작 확인



    웹 앱에 액세스하면 Keycloak로 리디렉션되었으며 계정 정보를 입력하면 성공적으로 index.html이 표시되었습니다.

    실제로 LDAP Attribute를 sAMAccountName으로 변경하는 것을 모르고 계정 정보를 입력해도 오류가 발생했습니다.

    Keycloak 로그를 보면
    KC-SERVICES0013: Failed authentication:
    org.keycloak.models.ModelException:
    User returned from LDAP has null username!
    Check configuration of your LDAP mappings.
    

    가 나와 해결까지 시간이 걸렸습니다.

    좋은 웹페이지 즐겨찾기