LDAPサーバーに REST API アクセス

別名: LDAPサーバーOpenDJを使おう(3)

[LDAPサーバーOpenDJを使おう(1)](http://qiita.com/yteraoka/items/289ae6a1194f96c30db5) の続きの [LDAPサーバーOpenDJを使おう(2)](http://qiita.com/yteraoka/items/bac7cabb9b98eee666ef) の続きです。いよいよ REST API の登場です。

LDAP で問い合わせるの面倒だから HTTP の REST API あったら便利だよねということです。OpenDJ にはそれ自身に組み込まれた HTTP サーバーと、任意の LDAP サーバーをバックエンドとして利用できる REST API Gateway がありますが、今回の紹介は前者です。

----

権限の問題が解決できずにずっと放置していましたが、もう OpenDJ を使うことはなさそうなので中途半端ですが公開します。なぜ使わないかというと各メジャーバージョンの最初のリリースしか公開されなくなり、Subscription を買わないと更新できなくなったからです。プロダクション環境で使うためには Subscription が必要です。

----

# 前提

次のコマンドでセットアップされた状態で始めます

```
$ setup \
   --cli \
   --baseDN dc=example,dc=com \
   --sampleData 5 \
   --ldapPort 1389 \
   --adminConnectorPort 4444 \
   --rootUserDN cn=Directory\ Manager \
   --rootUserPassword password \
   --enableStartTLS \
   --ldapsPort 1636 \
   --generateSelfSignedCertificate \
   --hostName localhost \
   --no-prompt \
   --noPropertiesFile \
   --acceptLicense
```

# HTTP サーバーを有効にする

status コマンド出力の Connection Handlers 部分。HTTP は無効になってます。

```
          --- Connection Handlers ---
Address:Port : Protocol               : State
-------------:------------------------:---------
--           : LDIF                   : Disabled
0.0.0.0:161  : SNMP                   : Disabled
0.0.0.0:1389 : LDAP (allows StartTLS) : Enabled
0.0.0.0:1636 : LDAPS                  : Enabled
0.0.0.0:1689 : JMX                    : Disabled
0.0.0.0:8080 : HTTP                   : Disabled
```

有効にします。

```
$ bin/dsconfig \
   set-connection-handler-prop \
   --hostname localhost \
   --port 4444 \
   --bindDN "cn=Directory Manager" \
   --bindPassword password \
   --handler-name "HTTP Connection Handler" \
   --set enabled:true \
   --no-prompt \
   --trustAll
```

```
          --- Connection Handlers ---
Address:Port : Protocol               : State
-------------:------------------------:---------
--           : LDIF                   : Disabled
0.0.0.0:161  : SNMP                   : Disabled
0.0.0.0:1389 : LDAP (allows StartTLS) : Enabled
0.0.0.0:1636 : LDAPS                  : Enabled
0.0.0.0:1689 : JMX                    : Disabled
0.0.0.0:8080 : HTTP                   : Enabled
```

有効になりました。

```
$ curl -v http://127.0.0.1:8080/?_prettyPrint=true
* About to connect() to 127.0.0.1 port 8080 (#0)
*   Trying 127.0.0.1... connected
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /?_prettyPrint=true HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: 127.0.0.1:8080
> Accept: */*
> 
< HTTP/1.1 401 Unauthorized
< Server: grizzly/2.3.3
< WWW-Authenticate: Basic realm="org.forgerock.opendj"
< Content-Type: application/json
< Date: Fri, 23 May 2014 15:24:20 GMT
< Content-Length: 89
< 
{
    "code": 401,
    "message": "Invalid Credentials",
    "reason": "Unauthorized"
}
* Connection #0 to host 127.0.0.1 left intact
* Closing connection #0
```

動いてるっぽい。けれども `401` が返って来てるので認証が必要みたいです。(認証不要にもできますけどやらないですよね)

# HTTP でアクセスしてみる

setup コマンドで作成されたサンプルデータ内のユーザー(user.0 .. user.4)のパスワードは `password` でしたので curl の `--user` オプションで渡してます。

```
$ curl --user user.0:password 'http://localhost:8080/users/user.0?_prettyPrint=true'
{
  "_rev" : "000000005049b1ed",
  "schemas" : [ "urn:scim:schemas:core:1.0" ],
  "contactInformation" : {
    "telephoneNumber" : "+1 685 622 6202",
    "emailAddress" : "user.0@maildomain.net"
  },
  "_id" : "user.0",
  "name" : {
    "familyName" : "Amar",
    "givenName" : "Aaccf"
  },
  "userName" : "user.0@maildomain.net",
  "displayName" : "Aaccf Amar"
}
```

ユーザー情報が取得できました。`uid` が `_id` として返ってきてます。`userName` は `mail` で `displayName` は `cn` ですね。これらのマッピングの定義は `config/http-config.json` に書かれています。

```
$ bin/ldapsearch \
    --hostname localhost \
    --port 1389 \
    --baseDN "dc=example,dc=com" \
    "uid=user.0"

dn: uid=user.0,ou=People,dc=example,dc=com
postalAddress: Aaccf Amar$01251 Chestnut Street$Panama City, DE  50369
postalCode: 50369
description: This is the description for Aaccf Amar.
uid: user.0
employeeNumber: 0
initials: ASA
givenName: Aaccf
objectClass: person
objectClass: inetorgperson
objectClass: organizationalperson
objectClass: top
pager: +1 779 041 6341
mobile: +1 010 154 3228
cn: Aaccf Amar
sn: Amar
telephoneNumber: +1 685 622 6202
street: 01251 Chestnut Street
homePhone: +1 225 216 5900
l: Panama City
mail: user.0@maildomain.net
st: DE
```

別ユーザーの情報も取得できます。

```
$ curl --user user.0:password 'http://localhost:8080/users/ser.1?_prettyPrint=true'
{
  "_rev" : "00000000950cacbf",
  "schemas" : [ "urn:scim:schemas:core:1.0" ],
  "contactInformation" : {
    "telephoneNumber" : "+1 390 103 6917",
    "emailAddress" : "user.1@maildomain.net"
  },
  "_id" : "user.1",
  "name" : {
    "familyName" : "Atp",
    "givenName" : "Aaren"
  },
  "userName" : "user.1@maildomain.net",
  "displayName" : "Aaren Atp"
}
```

## データを変更してみる

それではユーザーの追加を試してみましょう。まず、追加リクエスト用の JSON ファイルを作ります。

```json:useradd.json
{
  "_id": "user.5",
  "contactInformation": {
    "emailAddress": "user.5@example.com"
  },
  "name": {
    "familyName": "Abe",
    "givenName": "Shinzo"
  },
  "displayName": "Shinzo Abe"
}
```

```
$ curl --user user.0:password \
       -X POST \
       -H "Content-Type: application/json" \
       --data @useradd.json \
       "http://localhost:8080/users?_action=create&_prettyPrint=true"
{
  "code" : 403,
  "reason" : "Forbidden",
  "message" : "Insufficient Access Rights: アクセス権限が不十分なため、エントリ uid=user.5,ou=people,dc=example,dc=com を追加できません"
}
```

権限が足りないようです。一般ユーザーなんだから当然ですよね。
では user.0 さんに力を授けましょう。

```text:grant-all.ldif
dn: uid=user.0,ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (version 3.0;acl "Admin"; allow(all)(userdn = "ldap:///all");)
```

```
$ bin/ldapmodify \
    --hostname localhost \
    --port 1389 \
    --bindDN cn=Directory\ Manager \
    --bindPassword password \
    --defaultAdd \
    --filename grant-all.ldif

uid=user.0,ou=People,dc=example,dc=com の MODIFY 要求を処理しています
DN uid=user.0,ou=People,dc=example,dc=com に対して MODIFY の操作が成功しました
```

これで user.0 さんはほとんどの操作が可能になったはずです。ユーザー追加に再チャレンジ。

あれ？ダメですね。どうやれば良いのでしょう？

HTTPS への切り替えや SSL 証明書を入れ替える方法とかを書こうと思っていましたがここでおしまい。

ApacheDS 試してみようかな。