シングルサインオンサービスKeycloakとNextCloudを連携する

# TL;DR

* SSOサービスKeycloakと，クラウドストレージNextCloudを連携させる方法を説明します
    * KeycloakとNextCloudは，Dockerコンテナで稼働している状況で進めます
    * それぞれのセットアップ方法は関連記事を参考にしてください
        * [OSSなシングルサインオンサービスKeycloakをdockerで立ち上げる](https://qiita.com/myoshimi/items/7e9f1de7373427233880)
        * [高機能クラウドストレージNextCloudをdocker-composeでセットアップする](https://qiita.com/myoshimi/items/fc3739221e7e711867b9)
* Keycloakと他のサービスとの連携記事も参考にしてください
    * [GitLabを連携する](https://qiita.com/myoshimi/items/37c90c2a63dca295edb4)
    * [WikiシステムGrowiを連携する](https://qiita.com/myoshimi/items/f26cf3f179602a12a5ac)

# 設定手順

* KeycloakとNextCloudの連携は，以下の手順で行います
    * KeycloakのRealmに，NextCloud用のClientを作成し，設定します
    * NextCloudで，Keycloakに接続する設定を行います

# Keycloak設定

* Keycloakに管理者権限でログインし，Nextcloudと連携したいRealmを選択します
* "Clients"から"Create"を選択します
* ClientIDを，```https://nextcloud.example.com/apps/user_saml/saml/metadata``` のように，NextcloudのURLに，"/apps/user_saml/saml/metadata"を付与したものに設定します
    * NextCloud側が固定されたClientIDでアクセスするので，Client IDはこのようにURLに設定する必要があります
    * (190820追記) NextCloud 16.0.4から，```https://nextcloud.example.com/index.php/apps/user_saml/saml/metadata```に変更されているようです
* Client Protocolを"saml"でClientを作成します．

## Settingsタブ

| フィールド名              | 値                                                                   |
| ------------------------- | -------------------------------------------------------------------- |
| Client Signature Required | OFF                                                                  |
| Root URL                  | NextCloudのURL(e.g. ```https://nextcloud.example.com```)             |
| Valid Redirect URIs       | NextCloudのURL以下の領域 (e.g. ```https://nextcloud.example.com/*``` |

## Mappersタブ

* username, email, role listの3つを設定します
    * ![01_mappers.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/1063d04a-274d-54f7-3fcf-5ffe7ac90ee9.jpeg)


* usernameとemailをマップします

| Name       | Mapper Type   | Property  | Friendly Name | SAML Attribute Name | SAML Attribute NameFormat |
| ---------- | ------------- | --------- | ------------- | ------------------- | ------------------------- |
| username | username | username  | username      | username                | Basic                     |
| email      | User Property | email     | email         | email               | Basic                     |

* さらに，Role Listを作成します
    * ![02_roles.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/34424faa-d25e-9be1-a084-28361d2e55bb.jpeg)


| フィールド                | 値        |
| ------------------------- | --------- |
| Name                      | role list |
| Mapper Type               | Role list |
| Role attribute name       | Role      |
| Friendly Name             |           |
| SAML Attribute NameFormat | Basic     |
| Single Role Agttribute | チェック          |

# NextCloud設定


## （オプション）リダイレクト設定

* NextCloudをリバースプロキシの背後にある場合，ログイン処理後のリダイレクト先がnginxで指定しているホスト名に変わってしまうので， NextCloudの```config/config.php```に，以下の2つの項目を追加してコンテナを再起動して，正しく動作するように修正します
    * もし未設定であれば，設定してください

```php
<?php
$CONFIG = array (
  .....<snip>.....
  'overwritehost' => 'nextcloud.example.com',
  'overwriteprotocol' => 'https',
  .....<snip>.....
);
```

## 準備

* [高機能クラウドストレージNextCloudをdocker-composeでセットアップする](https://qiita.com/myoshimi/items/fc3739221e7e711867b9)の記事で説明したNextCloud(バージョンアップに応じてnextcloud:16.0.1-apacheに変更します)と，nginxによるリバースプロキシ環境で行います
* adminユーザでログインします

## SAMLアプリ設定

* NextCloud公式は，"SSO & SAML authentication"アプリケーションを提供しているので，こちらを使います
* ログイン画面後の右上にあるユーザ記号をクリックして"アプリ"をクリックします
    * ![03_application.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/397def75-5b8b-9725-e719-983c6b6a8f4b.jpeg)
* 左側メニューから"連携"カテゴリをクリックし，"SSO & SAML authentication"について，"ダウンロードして有効化する"をクリックします
    * ![04_ssoApplication.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/665bcd2a-3855-bab9-09b8-dea5f7b3428c.jpeg)
* インストールが完了したら，右上にあるユーザ記号をクリックして"設定"をクリックします
    * 管理者権限を持っていると表示される"管理"カテゴリに，"SSOとSAML認証"メニューが表示されているので，クリックします
    * <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/3c1e1bb6-c68d-844e-56eb-b4dc42925346.jpeg" width=50%>
    * "組み込みのSAML認証を使用する"をクリックし，設定フォームに必要な情報を記入します
        * <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/c5ea0757-ff92-fdd2-bced-19a7c1a3739b.jpeg" width=80%>

| 設定フォーム                                                                     | 設定値                                                |
| -------------------------------------------------------------------------------- | ----------------------------------------------------- |
| Nextcloud デスクトップクライアントにSAML認証を使用する（ユーザーの再認証が必要） | チェック **しない**                                               |
| 複数のユーザーのバックエンド（LDAPなど）の使用を許可する | チェック |
| UIDをマップする属性                                                              | username                                              |
| IdPエンティティの識別子                                                          | https://sso.example.com/auth/realms/dev               |
| SPが認証要求メッセージを送信するIdPのURLターゲット                               | https://sso.example.com/auth/realms/dev/protocol/saml |
| IdPの公開X509証明書                                                              | 後述                                                  |
| 表示名をマップする属性                                                           | username                                              |
| 電子メールアドレスをマップする属性                                               | email                                                 |

## 公開X.509証明書について

* 以下のURLから```<dsig:X509Certificate>```タグ内の，MII〜で始まる文字列をコピーします

```bash
https://sso.example.com/auth/realms/dev/protocol/saml/descriptor
```

* コピーした文字列の先頭に```-----BEGIN CERTIFICATE-----```の行を，末尾に```-----END CERTIFICATE-----```の行を付与して，フォームに記入します

# 動作確認

* 別のブラウザで，NextCloudのログイン画面にアクセスします
    * NextCloudをログアウトしてしまうと，
    * "SSO & SAML log in"ボタンが表示されることを確認します
    * ![07_login.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/8ac799ed-5df6-0046-29b4-51925b4d5ed9.jpeg)
* "SSO & SAML log in"ボタンをクリックすると，Keycloakのログイン画面に遷移するので，当該Realmに登録されたユーザでログインを試みます
    * ![08_keycloak.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/d2888654-8991-a4d5-d477-2d263fe41eed.jpeg)
* NextCloudにログインできれば成功です
    * ![09_nextcloud.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309617/018b53fd-fdeb-a222-e14d-7f335223f5dd.jpeg)

# 参考

* [OSSなシングルサインオンサービスKeycloakをdockerで立ち上げる](https://qiita.com/myoshimi/items/7e9f1de7373427233880)
* [高機能クラウドストレージNextCloudをdocker-composeでセットアップする](https://qiita.com/myoshimi/items/fc3739221e7e711867b9)
* [シングルサインオンサービスKeycloakとGitLabを連携する](https://qiita.com/myoshimi/items/37c90c2a63dca295edb4)
* [シングルサインオンサービスKeycloakとWikiシステムGrowiを連携する](https://qiita.com/myoshimi/items/f26cf3f179602a12a5ac)