OpenAMからG SuiteにFederationして、Single Sign-onする

## 今日やること

タイトルの通りです。タイトルのことを実現するための設定と、実際どんな情報が連携されているのかをみてみましょう。

![017.jpg](https://qiita-image-store.s3.amazonaws.com/0/148404/6bfa7e7a-dedb-bb7d-e1c3-841a8e1fa500.jpeg)

## 前提条件

* G Suiteの設定が完了している
* G Suiteの管理者アカウントで`https://admin.google.com/`にアクセスできる

本手順では、G Suiteは以下の設定で完了しているものとします。

* ドメイン名
    * hitori.example.com
* 管理者アカウントのID
    * johnd@hitori.example.com

## OpenAMの設定

まず、OpenAMをSAML IDPとして設定します。

管理者アカウント（`amadmin`）でサインイン後、**Configure SAMLv2 Provider**をクリックします。

<img width="729" alt="009 - コピー.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/e0fc5422-8362-359e-7e3e-ec056c605b40.jpeg">

次に**Create Hosted Identity Provider**をクリックします。

<img width="734" alt="010.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/8886871f-908a-e9b8-7613-499fa612b9cb.jpeg">

SAMLはアサーション情報をやりとりするノードを**Circle of Trust**という枠組みに登録する必要があります。初期設定時には既存のCircle of Trustは存在しないので、新しく作成します。

ここでは新しいトラストサークルの名前を`hitoricot`としています。

<img width="576" alt="011.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/de977b55-d3ba-ce46-5633-ada40bb8c48b.jpeg">

ダッシュボードにもどり、次は**Configure Google Apps**をクリックします。

<img width="729" alt="009.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/c63d29e4-de3f-4a55-a05d-4f4139b83c3a.jpeg">

G Suiteで設定したドメイン名を入力します。（実際には私物のサブドメインを使っているので、画像ではマスクしています）

<img width="470" alt="012.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/fc0f8cba-0103-b968-f743-c6e95e29fba7.jpeg">

続いて、シングルサインオンの設定画面が表示されますので、各項の設定をコピーしてメモ帳に貼っておきます。

* URL
    * サインインページのURL
    * サインアウトページのURL
    * パスワード変更のURL
* 検証証明書
    * **ダウンロードするには、ここをクリックします**をクリックして、証明書のテキストファイルをダウンロードしておきます。
    * ファイル名を`OpenSSOCert.txt`とします。

<img width="807" alt="013.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/fdb55c37-0676-2715-1ba6-69851dd041e2.jpeg">

## G Suiteの設定

続いて、管理者アカウントでGoogleにサインイン後、`https://admin.google.com/`にアクセスします。

**セキュリティ**をクリックし、

<img width="817" alt="007.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/4995008b-5fa4-2e75-8250-f2b9de9aebf8.jpeg">

シングルサインオンの設定をクリックします。

<img width="611" alt="008.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/1da92519-f475-c055-512c-a9c3f16795b6.jpeg">

先ほど、OpenAMの設定で表示された**シングルサインオンの設定**の各項のパラメータを入力します。ダウンロードした検証証明書（`OpenSSOCert.txt`）はアップロードをします。
また、**ドメイン固有の発行元を使用**にチェックをいれます。

<img width="605" alt="016.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/0e906d41-7b40-fbb0-e0ee-68d31bf20159.jpeg">

## 動作確認

まず、`https://mail.google.com/a/hitori.example.com`にアクセスします。
この時、OpenAMにリダイレクトされますが、以下のSAML Authentication RequestのメッセージがOpenAMに送信されています。OpenID Connectでいう認可リクエストみたいなもんですかね。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<samlp :AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
       ID="ldidjogolljaiakiomfajpdemjmcpgpandoeljjn"
       Version="2.0"
       IssueInstant="2016-12-20T11:04:09Z"
       ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
       ProviderName="google.com"
       IsPassive="false"
       AssertionConsumerServiceURL="https://www.google.com/a/hitori.example.com/acs">
  <saml :Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">google.com/a/hitori.example.com</saml:Issuer>
  <samlp :NameIDPolicy AllowCreate="true"
         Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" />
</samlp:AuthnRequest>
```

続いて、OpenAMで認証します。このとき認証に使用するユーザーはすでにG Suite側に作られている`johnd`とします。
サインイン後、今度はG Suiteがわに以下のSAML Authenticaiton Responseが送信されます。

```xml
<samlp :Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
       ID="s204b678155001cdc0dd6747339cb5596fbe2af353"
       InResponseTo="ldidjogolljaiakiomfajpdemjmcpgpandoeljjn"
       Version="2.0"
       IssueInstant="2016-12-20T11:03:55Z"
       Destination="https://www.google.com/a/hitori.example.com/acs">
  <saml :Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://iam.example.com:443/openam</saml:Issuer>
  <samlp :Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
    <samlp :StatusCode xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
           Value="urn:oasis:names:tc:SAML:2.0:status:Success"></samlp:StatusCode>
  </samlp:Status>
  <saml :Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
        ID="s2a5b8576771767a431f0b27fa567758a01e107bfe"
        IssueInstant="2016-12-20T11:03:55Z"
        Version="2.0">
    <saml:Issuer>https://iam.example.com:443/openam</saml:Issuer>
    <ds :Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:SignedInfo>
        <ds :CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        <ds :SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
        <ds :Reference URI="#s2a5b8576771767a431f0b27fa567758a01e107bfe">
          <ds:Transforms>
            <ds :Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
            <ds :Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          </ds:Transforms>
          <ds :DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
          <ds:DigestValue>TFsfKzPue1/C29wSUhvZ+vuzudE=</ds:DigestValue>
        </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>
hCBpA7tixvSf4vU+7Tbck9nIbCp21gqz6n49/q5CnriJZZ4oqqPd6uUrGD7GM0YAA8IvTf5N9RKz
gHEZILPxTv8WP2ZDwxBNLIKNIE4FAG19kX8WeVNgFjawg5YkEnJiJRKXtzlzIUGW6/T6BcY2zdZm
XpBANRgGbgsndJF4cou1m8X16y+0ulcwPJGuU/tnqGr71j0y7mDOUhNQhau/SLBmDHVrFml0QE+z
sDfmAOb9cRfQp3FiayhUqn16DYgqiK5+/7NOC9QKCcGpi4wyvmSn6QnIrjBrR35pVzI0cT72WQD6
FUT4KV36r7FibjYv6BxxZ6Z7LsLB1sHrG7Acpg==
</ds:SignatureValue>
      <ds:KeyInfo>
        <ds:X509Data>
          <ds:X509Certificate>
MIIDaDCCAlCgAwIBAgIDcB/YMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVLMRAwDgYDVQQI
EwdCcmlzdG9sMRAwDgYDVQQHEwdCcmlzdG9sMRIwEAYDVQQKEwlGb3JnZVJvY2sxDzANBgNVBAsT
Bk9wZW5BTTENMAsGA1UEAxMEdGVzdDAeFw0xNjAzMTgxMTU2MjhaFw0yNjAzMTYxMTU2MjhaMGUx
CzAJBgNVBAYTAlVLMRAwDgYDVQQIEwdCcmlzdG9sMRAwDgYDVQQHEwdCcmlzdG9sMRIwEAYDVQQK
EwlGb3JnZVJvY2sxDzANBgNVBAsTBk9wZW5BTTENMAsGA1UEAxMEdGVzdDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAKNbl89eP6B8kZATNSPe3+OZ3esLx31hjX+dakHtPwXCAaCKqJFw
jwKdxyRuPdsVG+8Dbk3PGhk26aJrSE93EpxeqmQqxNPMeD+N0/8pjkuVYWwPIQ/ts2iTiWOVn7wz
lE4ASfvupqOR5pjuYMWNo/pd4L7QNjUCKoAt9H11HMyiP+6roo/EYgX4AH7OAhfUMncYsopWhkW/
ze9z8wTXc8BAEgDmt8zFCez1CtqJxxxxxBUGDgk8oHYDsHKmx05baBaOBQ8LRGP5SULSbRtu34eL
FootBIn0FvUZSnwTiSpbaHHRgWrMOVm07oSLWBuO3h/bj38zBuuqqVsAK8YuyoECAwEAAaMhMB8w
HQYDVR0OBBYEFHxfAbr6PQ5Xgc+jVx+AGTPnnpWZMA0GCSqGSIb3DQEBCwUAA4IBAQAZBMJ29/2i
dv1ztC6ArHtB4kw/nHHwthXFwtWAN7sRPB8tLW7fD8aJ43RQr5107Bg1Lgkmt+FZxpafqUC/mukj
IzGzbW0COMSOTcWUGss+HxK6M6Fl9aOzKJMct1uOSpPFgjItcGqydGZXR2FH93vXWoAotUwtZ119
IixIdxpOJwYJg0HFn+GEfpU1PmiLfq2/uwqJ0hGCNfNcm9puagzhQrcDFOnolxjnYPSfSkU5wxlG
o99yE5eJwoHXXU7csaZVttmx7sPj1lUENogXUM6JMqzSyEIm1XCOCL8rZJkZ781W5CwZhuJTNzV3
1sBREs8FaaCeksu7Y48BmkUqw6E9
</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </ds:Signature>
    <saml:Subject>
      <saml :NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
            NameQualifier="https://iam.example.com:443/openam"
            SPNameQualifier="google.com/a/hitori.example.com">johnd</saml:NameID>
      <saml :SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <saml :SubjectConfirmationData InResponseTo="ldidjogolljaiakiomfajpdemjmcpgpandoeljjn"
              NotOnOrAfter="2016-12-20T11:13:55Z"
              Recipient="https://www.google.com/a/hitori.example.com/acs" />
      </saml:SubjectConfirmation>
    </saml:Subject>
    <saml :Conditions NotBefore="2016-12-20T10:53:55Z"
          NotOnOrAfter="2016-12-20T11:13:55Z">
      <saml:AudienceRestriction>
        <saml:Audience>google.com/a/hitori.example.com</saml:Audience>
      </saml:AudienceRestriction>
    </saml:Conditions>
    <saml :AuthnStatement AuthnInstant="2016-12-20T11:03:55Z"
          SessionIndex="s264729ca9bbf7e7126ef834036fe96ffcf8cd4c01">
      <saml:AuthnContext>
        <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
      </saml:AuthnContext>
    </saml:AuthnStatement>
  </saml:Assertion>
</samlp:Response>
```

XMLということもあり、コンテンツのサイズが大きく見えますが、その内容は**ID Token**とあまりかわらないですね。issとかaudもあるし、subはNameIDかな？

このSAML Authenticaiton ResponseがG Suiteに返却されると、G Suiteはこのメッセージの検証をし、認証を完了させる（シングルサインオンさせる）といった動きになります。

<img width="647" alt="018.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/148404/a92e17fa-9d88-a872-0890-f84e45323b37.jpeg">

## まとめ

SAMLをつかったIdentity Federationの代表例として、G Suiteへのシングルサインオンの手順を掲載しました。実際、G Suiteのデモ環境の準備時間も入れて、1時間ぐらいで作業が完了できるぐらい簡単に試せるので、SAMLのメッセージやメッセージをどうやって伝えてるのかを見てみたい人は、この方法がよいかと思いました。

ん～、わたしはSAMLの勉強のモチベーションがあがらないんですよね～。なんでだろう。メッセージがXMLだからかな？まぁ、時間取れたら勉強しましょ。( ˘•ω•˘ )
（~~ぶっちゃけ世の中のSAMLのユースケースのほとんどがSSOだし、アサーションとバインディングだけわかってたらなんとかなるんじゃないのかなぁ？~~）
モチベーションがあがりそうなトピックがあったらいいんですけどね～。

あしたはなにしよう～？

ばい！