Sync Gatewayセキュリティ：ユーザー認証


## 概要

Sync Gatewayは、次の認証方法をサポートしています。

### 匿名アクセス
Sync Gatewayは、デフォルトでは匿名アクセスまたはゲストアクセスを許可しませんが、設定により有効にすることができます。

### 基本認証
ユーザーを認証するためのユーザー名とパスワードを利用します。

### 認証プロバイダー
Sync Gatewayは、FacebookまたはGoogleで認証するためのターンキーソリューションを提供します。
他のプロバイダーの場合は、カスタム認証またはOpenID　Connectを使用することができます。

#### カスタム認証 
アプリケーションサーバーを使用して認証を自分で処理し、Sync Gateway Admin REST　APIでユーザーセッションを作成します。

#### OpenID Connect認証
OpenID Connectプロバイダー（Google+、Paypalなど）を使用してユーザーを認証します。Sync Gatewayは現在、Facebook、Google+、およびOpenID Connectプロバイダーの認証エンドポイントをサポートしています

## 匿名アクセス
Sync Gatewayでは、「GUEST」という名前の付いた特別なユーザーアカウントが、認証されていないリクエストに適用されます。AuthorizationヘッダーまたはセッションCookieを持たないパブリックREST　APIへのリクエストは、GUESTアカウントからのものとして扱われます。このアカウントとすべての匿名アクセスはデフォルトで無効になっています。

GUESTアカウントを有効にするには、`disabled`プロパティを`false`に設定します。また、GUESTアカウントに対して、特定のチャネルへのアクセスを許可することもできます。チャネルをGUESTアカウントに割り当てないと、匿名のリクエストはどのドキュメントにもアクセスできません。次のコマンドは、GUESTアカウントを有効にし、publicという名前のチャネルへのアクセスを許可します。

```BASH
$ curl -X PUT localhost:4985/$DB/_user/GUEST --data \
   '{"disabled":false, "admin_channels":["public"]}'
```

## 基本認証
Sync Gatewayでユーザーが作成されたら、Couchbase Liteアプリケーションで、そのユーザー/パスワードを使用できます（`BasicAuthenticator`クラス）。内部的には、レプリケーターは最初のリクエストでクレデンシャルを送信してSync Gateway Session Cookieを取得し、レプリケーション中の後続のすべてのリクエストに使用します。これは、基本認証を使用するための推奨される方法です。

## 認証プロバイダー
Sync Gatewayは、FacebookまたはGoogleで認証するためのターンキーソリューションを提供します。

アプリは認証プロバイダートークンを取得する責任があり、セッションIDを返すSync Gatewayに送信する必要があります。返されたセッションIDは、Couchbase Liteレプリケーターの構成、またはSync Gateway REST APIへの他のHTTP要求に使用できます。

次の図は、一連の手順を示しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/f231d320-d3ba-82ec-b105-df905b45944d.png)


上記図にあるように、Sync Gatewayは、下記のエンドポイントを提供します。

- `/{db}/_facebook`

- `/{db}/_google`


## カスタム認証
リモートのSync Gatewayに関連付けられたアプリケーションサーバーが、独自のカスタム形式の認証を提供することが可能です。通常、これには、アプリが何らかの形式のクレデンシャルを投稿する必要がある特定のURLが含まれます。App Serverはそれらを確認し、Sync Gatewayに、対応するユーザーの新しいセッションを作成し、クライアントアプリへの応答でセッション資格情報を返すように指示します。

次の図は、Couchbase MobileアプリケーションでGoogleサインインをサポートするアーキテクチャの例を示しています。クライアントはアクセストークンをApp Serverに送信し、サーバー側の検証がGoogle APIで実行され、対応するSync Gatewayユーザーが作成されます。最後のリクエストでセッションが作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/ff1aed5b-a3fc-d65b-4da1-8775ea79dc8e.png)


### カスタム認証フロー
すでに作成されているユーザーを指定すると、そのユーザーの新しいセッションをAdmin POST `/{db}/_session`エンドポイントで作成できます。

```BASH
$ curl -vX POST -H 'Content-Type: application/json' \
        -d '{"name": "john", "ttl": 180}' \
        http://localhost:4985/sync_gateway/_session
// Response message body
{
  "session_id": "904ac010862f37c8dd99015a33ab5a3565fd8447",
  "expires": "2015-09-23T17:27:17.555065803+01:00",
  "cookie_name": "SyncGatewaySession"
}
```

HTTP応答本文には、セッションの資格情報が含まれています。

- 名前は`cookie_name`に対応します

- 値は`session_id`に対応します

- パスはSync Gatewayのホスト名です

- `expireDate`は、Cookieの有効期限に対応します。ユーザーセッションアクティビティに応じて有効期限が自動的に延長することができます（APIリファレンスには、詳細情報が含まれています。

- **secure**: Cookieを安全なプロトコル（HTTPSなど）を使用してのみ送信するかどうか

- **httpOnly**: CookieをHTTPまたはHTTPSのどちらのリクエストを送信する場合にのみ使用するか、したがって他の非HTTPAPIからのアクセスを制限するかどうか

同じ形式でセッションの詳細をクライアントアプリケーションに返し、SessionAuthenticatorクラスを使用してそのセッションIDで認証することをお勧めします。



## OpenID Connect
Sync GatewayはOpenID Connectをサポートしています。これにより、認証をサードパーティサーバー（プロバイダーと呼ばれる）に委任できます。OpenID Connectで使用できる実装方法は2つあります。

#### 暗黙フロー(Implicit Flow)
この方法では、IDトークンの取得はデバイス上で行われます。次に、IDトークンを使用してパブリックREST APIのPOSTエンドポイント`/{tkn-db}/_session`を使用してユーザーセッションを作成できます。

#### 認証コードフロー
この方法では、Sync Gatewayに依存してIDトークンを取得します。
Sync Gatewayは認証コードフローをサポートしていますが、クライアント側で認証コードフローを実装するにはかなりの作業が必要です。Couchbase Lite 1.xには、この複雑さを隠すためのAPI `OpenIDConnectAuthenticator`がありますが、2.0 APIでは使用できません。
ここでは、暗黙的なフローについて紹介し、認証コードフローについては割愛します。

### 暗黙フロー
暗黙フローには、クライアントが独自のOpen IDトークンを取得し、それを使用してSync Gatewayに対して認証できるようにするという重要な機能があります。Sync Gatewayの暗黙的なフローは次のとおりです。

1. クライアントは、署名されたOpenIDトークンをOpenID Connectプロバイダーから直接取得します。署名されたトークンのみがサポートされていることに注意してください。送信されているOpenIDトークンが実際に署名されていることを確認するには、jwt.ioデバッガーを使用できます。アルゴリズムのドロップダウンで、署名アルゴリズムとしてRS256を選択してください（HS256などの他のオプションは、Sync Gatewayでまだサポートされていません）。

2. クライアントには、Authorization: Bearer <id_token>Sync Gateway RESTAPIに対して行われたリクエストのヘッダーとしてOpenIDトークンが含まれています。

3. Sync Gatewayは、トークン内の発行者とオーディエンスに基づいて、構成ファイル内のプロバイダーとトークンを照合します。

4. Sync Gatewayは、プロバイダー定義に基づいてトークンを検証します。

5. 検証が成功すると、Sync Gatewayは、トークン内のサブジェクトと発行者に基づいてユーザーを認証します。

6. 通常、Open IDトークンは大きいため、通常のアプローチでは、Open IDトークンを使用して同期ゲートウェイセッションIDを取得し（POST `/db /_session`エンドポイントを使用）、返されたセッションIDを後続の認証要求に使用します。

#### REST API

```BASH
curl --location --request PUT 'http://localhost:4985/ourdb/_config' \
--header 'accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
  oidc: {
    providers: {
      google_implicit: {
        issuer:https://accounts.google.com,
        client_id:yourclientid-uso.apps.googleusercontent.com,
        register:true 
      },
    },
  }
}'
```

#### 構成ファイル
以下は、暗黙的なフローを使用するように構成されたSync Gateway構成ファイルです。

```JSON
{
  "databases": {
    "default": {
      "name": "dbname",
      "bucket": "default",
      "oidc": {
        "providers": {
          "google_implicit": {
            "issuer":"https://accounts.google.com",
            "client_id":"yourclientid-uso.apps.googleusercontent.com",
            "register":true 
          },
        },
      }
    }
  }
}
```

register検証が正常に完了したときにSync Gatewayユーザーを自動登録するために使用します。

#### クライアント認証
暗黙的なフローでは、トークンとSync Gatewayセッションを更新するメカニズムをアプリケーションコードで処理する必要があります。起動時に、アプリケーションはトークンの有効期限が切れているかどうかを確認する必要があります。持っている場合は、新しいトークンをリクエストする必要があります（iOS用のGoogleサインインには、この目的のために呼び出されるメソッド`signInSilently`があります）。これにより、アプリケーションはトークンを使用してSync Gatewayセッションを作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/907603ae-cbad-44e8-676b-2785b881bb64.png)

### クライアント認証
1. Google SignIn SDKはユーザーにログインを促し、成功するとIDトークンをアプリケーションに返します。

2. IDトークンは、POST`/{tkn-db}/_session`リクエストを送信してSync Gatewayセッションを作成するために使用されます。

3. Sync Gatewayは、応答ヘッダーでCookieセッションを返します。

4. Sync GatewayのCookieセッションは、レプリケータオブジェクトで使用されます。

Sync Gatewayセッションにも有効期限があります。その場合、レプリケーション`lastError`プロパティは「401 Unauthorized」を返します。アプリケーションは新しいSync Gatewayセッションを開始し、レプリケータに新しいCookieを設定する必要があります。

以下に、完全なチュートリアルがあります。

[Set up an OpenID Connect authentication for the Sync Gateway](https://docs.couchbase.com/tutorials/openid-connect-implicit-flow/index.html)




## 関連情報

https://docs.couchbase.com/sync-gateway/3.0/authentication-users.html