現在のプランを確認
Suite Team、Growth、Professional、EnterpriseまたはEnterprise Plus
Support Team、ProfessionalまたはEnterprise

シングルサインオン認証の中核となるのは、システムから取得したログイン要求をZendeskが信頼できるようにするJSON Web Token(JWT)というテクノロジーです。詳細については、「JWT(JSON Webトークン)を使用したシングルサインオンの設定」を参照してください。

Zendesk SSOインテグレーションの場合、サーバー側のメカニズムがJWTを生成し、ユーザーのブラウザをZendesk固有のURLにリダイレクトして、HTTPヘッダーではなくクエリ文字列のパラメーターとしてJWTを渡す必要があります。

JWTは通常、ピリオド(.)で区切られた3つの部分で構成されます。それぞれ、ヘッダー、ペイロード、署名と呼ばれ、JWT内で異なる役割を果たします。

重要:SSOセキュリティでは、HTTP GETリクエストではなく、HTTP POSTリクエストを使用することが推奨されています。HTTP POSTを使用すると、ユーザーデータはリクエストのボディに渡されます。HTTP GETリクエストでは、ユーザーに関連するデータ(電話番号やタグなど)がJWTとともにURLで渡されるため、ブラウザの履歴やキャッシュに保存され、情報漏洩のリスクにさらされる可能性があります。

この記事では、以下のトピックについて説明します。

  • チャンク1:JWTヘッダー
  • チャンク2:JWTクレームセット/ペイロード
  • チャンク3:JWS署名

チャンク1:JWTヘッダー

最初のチャンクはJWTヘッダーです。これは、JWTリクエストであることを示し、使用されているハッシュアルゴリズムのタイプを示します。(詳細は後述します。)

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9

この部分(および残りのデータ)の大きな特徴は、base64でエンコードされていることです。これは実際には暗号化されていないので、次のようなツールで簡単にデコードできます。

  • Webツール:http://www.base64decode.org/
  • ターミナル:http://drewsymo.com/how-to/quick-and-simple-base64-encode-on-mac-osx-terminal/

デコードされた文字列は次のようになります。

{"typ":"JWT",
"alg":"HS256"}

JSON構造をとり、実質的に型を意味する2つのキーと値のペア、type: JWT と Algorithm: HMAC SHA 256 があることがわかります。SHA256は、米国家安全保障局によって設計された256ビット暗号化アルゴリズムです。 第3のチャンク、つまり署名を生成するために使用されます。これについては、後で説明します。

チャンク2:JWTクレームセット/ペイロード

2番目のチャンクはペイロードを含むため、かなり長くなります。これは「JWTクレームセット」として知られています。

eyJpYXQiOjEzNzIxMTMzMDUsImp0aSI6ODg4MzM2MjUzMTE5Ni4zMjYsIm5hbWUiOiJUZXN0IFVzZXIiLCJlbWFpbCI6InR1c2VyQGV4YW1wbGUub3JnIiwiZXh0ZXJuYWxfaWQiOiI1Njc4Iiwib3JnYW5pemF0aW9uIjoiQXBwbGUiLCJ0YWdzIjoidmlwX3VzZXIiLCJyZW1vdGVfcGhvdG9fdXJsIjoiaHR0cDovL21pdC56ZW5mcy5jb20vMjA2LzIwMTEvMDUvQmFybmFieV9NYXR0X2Nyb3BwZWQuanBnIiwibG9jYWxlX2lkIjoiOCJ9

これには、タイムスタンプ、ランダム値、ユーザー名、メールアドレス、外部ID、タグが含まれます。ほかにも使用できるオプションがあります。ペイロードを理解しやすいように、ここではbase64をデコードします。ここでは、読みやすいように改行しています。

{
"iat":1372113305,
"jti":8883362531196.326,
"name":"Test User",
"email":"tuser@example.org",
"external_id":"5678",
"organization":"Apple",
"tags":"vip_user",
"remote_photo_url":"http://mit.zenfs.com/206/2011/05/Barnaby_Matt_cropped.jpg",
"locale_id":"8"
}

必須プロパティ

iat

最初のキーはiatで、issued at(発行時刻):を表します。これは、1970年1月1日以降の整数秒としてフォーマットされたタイムスタンプであり、UNIXの標準的な時刻表現です。タイムスタンプは整数(小数なし)でなければならず、UTCである必要があります。また、Zendeskサーバーが受信した現在時刻から3分以内でなければなりません。これにより、各リモート認証リクエストに自己破壊メカニズムが追加され、生成されてから3分以上経過した単一のリクエストは使用されなくなります。

jti

2番目のキーjtiは、JSONトークンIDを表します。これは単なるランダムな文字列です。このため、再び使用される可能性が非常に低くなるように、十分に長くランダムである必要があります。偶然、別の認証リクエストに再利用された場合、そのリクエストは失敗します。これは使い捨ての鍵です。このようなランダム値を(強制的に)含めることで、同一の認証リクエストがないことを保証します。これにより、有効なリクエストURLが再利用されることがなくなります。たとえば、誰かがコンピュータまたはネットワークにマルウェアをインストールし、トラフィックログの記録を開始したとします。この誰かは、ユーザーがクリックしたすべてのURLを見ることができます。Zendeskへのログイン用に発行されたURLを見つけて取得した場合、この使い捨てキーがなかったら、3分以内にあなたの振りをしてログインできてしまいます。

名前

次はスペースを含むユーザーのフルネームです。Zendeskがここで受け取るものはすべて、以前に別の名前が設定されていたとしても、ユーザー名として設定されます。

メールアドレス

その後はユーザーのメールアドレスです。メールアドレスは常に必須です。外部IDを受け取らない限り、ユーザーの一意の識別子として使用されます*。つまり、メールアドレスと外部IDを受信した場合、最初にIDの照合を試みます。 その場合、指定されたメールアドレスでそのユーザーを更新します。

*メモ: オプション「外部IDの更新を許可しますか?」がZendeskで有効になっている場合、外部IDを受信しても引き続きメールアドレスによる特定を行います。メールと外部IDが異なる場合、外部IDを更新します。 

オプションのプロパティ

外部ID

外部IDは、メールアドレスを使用する代わりにユーザーを識別するために使用できるオプションのIDです(上述)。

組織

また、organization値を渡してユーザーを組織に追加することもできます。指定された組織はすでに存在し、名前が正確に一致している必要があります。それ以外の場合、アクションは実行されません。

タグ

tagsキーを使用すると、ログインしているユーザーにタグを設定できます。tagsキーは、ユーザーの既存のタグを指定したタグに置き換えるため、慎重に使用してください。空のタグパラメータを渡すと、ユーザーからすべてのタグが削除されます。

remote_photo_url

また、remote_photo_urlの値を渡すこともできます。この値は、写真を含むパブリックURLを受け取り、この写真をユーザーのプロフィール写真として設定します。

locale(言語) 

locale_idの値を渡して、Zendeskで認証済みユーザーの言語を設定または更新できます。この値は、Zendeskで現在アクティブになっているロケールに一致する数値である必要があります。ロケールは、APIのlocales.jsonエンドポイントを使用して見つけることができます:https://developer.zendesk.com/api-reference/ticketing/account-configuration/locales/#list-locales

ユーザーフィールド(上述の例には含まれない)

これは、各フィールドキーと値のキーと値のペアを含むJSONオブジェクトである必要があります。フィールドキーは、ユーザーフィールドインターフェイスで検索または定義できます。なお、渡すことができるのはカスタムユーザーフィールドのみです。

以下に例を示します。

"user_fields": {"checked": false,"date_joined": "2013-08-14T00:00:00+00:00","region": "EMEA","text_field": null}

チェックボックスはブール値を使用し、日付コードは上記の例に従います。ドロップダウンにはオプションの名前を指定します。テキストフィールドには文字列を指定します。

電話番号(上述の例には含まれない)

電話番号を示す文字列を指定します。電話番号を指定する際は、所定の形式に従ってください。詳細については、「Talkで利用できる電話番号の形式について」を参照してください。

チャンク3:JWS署名

リクエストの最後のチャンクは暗号化されています。それほど難しく考える必要はなく、基本的には上記のすべての情報(iat、jti、名前、メールなど)を共有シークレットとともに取得し、そのすべてから暗号化された文字列を生成します。次に、JWT標準に従って、その暗号化された文字列のチャンク(チェックサムと呼ばれる)が取得されます。それがJWS署名です。

では、どのように安全が保たれるのでしょうか。

暗号化された有効な文字列を生成するには、共有シークレットを知る必要があります。

暗号化は、暗号化された文字列からデータおよびキーまで逆方向に処理できないように設計されています。データの内容があっても、キーを推定することは事実上不可能です。

ただし、送り側と受け手側にそれぞれキーがあり、暗号化するのと同じデータを暗号化せずに送信するため、署名を自分で作成して、送信したものと一致することを確認できます。

また、転送中のデータを誰も改ざんできないことも保証されます。

擬似コードでは、次のように構築します。

URLBase64Encode( 
HMAC-SHA256(
URLBase64Encode( header_json ).URLBase64Encode( payload_json )
)
)

エンコードしたヘッダーとペイロードをHMAC-SHA256で生成するときには、共有シークレットを含めます。

結果は以下のようになります。

Zv9P7PNIcgHfxZaMwQtMpty3TZnmVHRWcsmAMM-mNHg

Powered by Zendesk