LoginSignup
5

More than 5 years have passed since last update.

LDAPを手っ取り早く使うときのメモ

Last updated at Posted at 2018-04-11

はじめに

  • spring-bootでLDAP認証したいと思ったが、実験環境が無かったのとLDAPの操作知識がなかったので勉強した。
  • spring-bootでLDAP認証する部分については言及しない
  • docker,docker-compose,docker-machineを利用しているがセットアップ方法は言及しない
  • LDAPの用語であるところのDN,CN,DCなどについても言及しない

環境

  • mac
  • Docker version 18.03.0-ce, build 0520e24
  • docker-compose version 1.20.1, build 5d8c71b

docker-compose

docker-compose.yml
version: '2'

services:
  openldap:
    image: osixia/openldap:latest
    container_name: test1-ldap
    environment:
      LDAP_ORGANISATION: "springframework"
      LDAP_DOMAIN: "springframework.org"
      LDAP_ADMIN_PASSWORD: "ldappw"
    ports:
      - "8389:389"

  admin:
    image: osixia/phpldapadmin:latest
    container_name: test1-ldapadmin
    environment:
      PHPLDAPADMIN_LDAP_HOSTS: "ldap"
      PHPLDAPADMIN_HTTPS: "false"
    ports:
      - "8080:80"
    links:
      - "openldap:ldap"
$ docker-compose up

補足

dockerコンテナのIPは下記で調べられる

$ docker-machine env default
set -gx DOCKER_TLS_VERIFY "1";
set -gx DOCKER_HOST "tcp://192.168.99.100:2376";
set -gx DOCKER_CERT_PATH "/Users/positrium/.docker/machine/machines/default";
set -gx DOCKER_MACHINE_NAME "default";
# Run this command to configure your shell:
# eval (docker-machine env default)

ldapコンテナに入る

$ docker container ls
CONTAINER ID        IMAGE                        COMMAND                 CREATED             STATUS              PORTS                            NAMES
3b011e09d113        osixia/phpldapadmin:latest   "/container/tool/run"   21 hours ago        Up 21 hours         443/tcp, 0.0.0.0:8080->80/tcp    test1-ldapadmin
570508cd3d27        osixia/openldap:latest       "/container/tool/run"   21 hours ago        Up 21 hours         636/tcp, 0.0.0.0:8389->389/tcp   test1-ldap

$ docker exec -it test1-ldap bash

注意

# /etc/init.d/slapd restart

を行うと、slapdのstopは出来たがstartが出来なかった。(Dockerの特徴?イメージの問題?)

ldapに適当なldifを読ませる

$ ldapadd -x -D 'cn=admin,dc=springframework,dc=org' -W -f test-server.ldif

正常に入ったら中身を下記で確認できるが、userPasswordはBase64.encode()されたものが出てくる。

$ slapcat
  • 下記、コメントアウト部分はコンテナによって自動作成されている部分
  • 他のエントリはspring-securityから
    • 小話: benのuserPasswordのrawはbenspasswordの筈だが、sha1Hexすると9c509e6d68f17da2db1c71b5424e54538b6b6ef4なので、実はbenspasswordではない気がする。
test-server.ldif
# dn: dc=springframework,dc=org
# objectClass: top
# objectClass: dcObject
# objectClass: organization
# o: springframework
# dc: springframework
# 
# dn: cn=admin,dc=springframework,dc=org
# objectClass: simpleSecurityObject
# objectClass: organizationalRole
# cn: admin
# description: LDAP administrator
# userPassword:: {SSHA}uKmKC5S1n62OuXyikGfXylLLNiTkFMt7

dn: ou=people,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: people

dn: ou=otherpeople,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: otherpeople

dn: uid=ben,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Ben Alex
sn: Alex
uid: ben
userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=

dn: uid=bob,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Bob Hamilton
sn: Hamilton
uid: bob
userPassword: bobspassword

dn: uid=joe,ou=otherpeople,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Joe Smeth
sn: Smeth
uid: joe
userPassword: joespassword

ldapsearch

uid=bobエントリを検索

$ ldapsearch -x -D 'cn=admin,dc=springframework,dc=org' -W -LLL -b 'ou=people,dc=springframework,dc=org' '(uid=bob)'
Enter LDAP Password:
dn: uid=bob,ou=people,dc=springframework,dc=org
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: Bob Hamilton
sn: Hamilton
uid: bob
userPassword:: Ym9ic3Bhc3N3b3Jk
  • ldif形式で出力される
  • ldif形式での::(userPassword:: Ym9ic3Bhc3N3b3Jk など)はバイナリ値を表す
  • userPasswordは、Base64.encode()されておりYm9ic3Bhc3N3b3Jkだが、デコードすると平文でbobspasswordが入っている。

ldapcompare

uid=benの存在有無比較

$ ldapcompare -x -D 'cn=admin,dc=springframework,dc=org' -W 'uid=ben,ou=people,dc=springframework,dc=org' 'uid: ben'
Enter LDAP Password: [冒頭のphpldapadminのPWを入力]
TRUE

java code sample

<!-- https://mvnrepository.com/artifact/com.unboundid/unboundid-ldapsdk -->
<dependency>
  <groupId>com.unboundid</groupId>
  <artifactId>unboundid-ldapsdk</artifactId>
  <version>4.0.5</version>
</dependency>
import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttribute;
import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;

public class Fuga {
    public static void main(String[] args) {
        Fuga fuga = new Fuga();
        try {
            fuga.go();
        } catch (LDAPException e) {
            e.printStackTrace();
        }
    }

    public void go() throws LDAPException {
        String address = "192.168.99.100";
        Integer port = 8389;
        String dn = "cn=admin,dc=springframework,dc=org";
        String pass = "ldappw";

        LDAPConnection c = new LDAPConnection();
        c.connect(address, port.intValue(), dn, pass);

        String user_dn = "uid=ben,ou=people,dc=springframework,dc=org";
        LDAPAttribute ldapAttribute = new LDAPAttribute("uid", "ben");

        if (c.compare(user_dn, ldapAttribute)) {
            System.out.println("OK");
        } else {
            System.out.println("NG");
        }
    }
}

OKとでる。

uid=bobの平文パスワード比較

$ ldapcompare -x -D 'cn=admin,dc=springframework,dc=org' -W 'uid=bob,ou=people,dc=springframework,dc=org' 'userPassword::Ym9ic3Bhc3N3b3Jk'
Enter LDAP Password:
TRUE
  • uid=bobのuserPasswordはbase64.encode()して保存されているので、base64.encode()された文字列を渡す。
  • ldifで::はバイナリ値を表すのと同じく、ldapcompareでも同様に::で値を指定する。

java code sample

import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPAttribute;
import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPConnection;
import com.unboundid.ldap.sdk.migrate.ldapjdk.LDAPException;

public class Fuga {
    public static void main(String[] args) {
        Fuga fuga = new Fuga();
        try {
            fuga.go();
        } catch (LDAPException e) {
            e.printStackTrace();
        }
    }

    public void go() throws LDAPException {
        String address = "192.168.99.100";
        Integer port = 8389;
        String dn = "cn=admin,dc=springframework,dc=org";
        String pass = "ldappw";

        LDAPConnection c = new LDAPConnection();
        c.connect(address, port.intValue(), dn, pass);

        String user_dn = "uid=bob,ou=people,dc=springframework,dc=org";
        LDAPAttribute ldapAttribute = new LDAPAttribute("userPassword", "bobspassword");

        if (c.compare(user_dn, ldapAttribute)) {
            System.out.println("OK");
        } else {
            System.out.println("NG");
        }
    }
}

OKとでた。勝手にBase64してくれたらしい。

uid=benのSHAパスワード比較

$ ldapcompare -x -D 'cn=admin,dc=springframework,dc=org' -W 'uid=ben,ou=people,dc=springframework,dc=org' 'userPassword::e1NIQX1uRkNlYldqeGZhTGJISEcxUWs1VVU0dHJidlE9'
Enter LDAP Password:
TRUE
  • userPasswordの指定に関しては前述同様
  • java sample codeについては、 小話参照で、現状、uid=benのuserPasswordのrawが不明なので書き換えてやらないといけない。書き換えずとも、{SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=を入れてやればいい筈だが、通常のパスワード入力値を想定したコードを書いているつもりなので、一手間あって面倒なので検証してない。

その他の暗号形式の場合

未検証だが、平文、SHA同様にBase64.encode()したバイナリ値を入力すればTRUEが返るはず。

参考図書

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5