9
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

python (pysaml2) から cybozu.com の SAML 認証を確認してみる

0.はじめに

python (pysaml2) から cybozu.com の SAML 認証を確認してみます。

1.Amazon Linux の EC2 インスタンスを作成する

  1. E2 コンソールページから、Amazon Linux の AMI を選択し、ポチポチと EC2 インスタンスを作成する。 
    • AMI ID :
      • amzn-ami-hvm-2017.03.0.20170417-x86_64-gp2 (ami-923d12f5)
    • Instance Type :
      • t2.micro
    • Security Groups :
      • SSH
      • HTTPS

  2. その後、Elastic IP を割り当てます。

2.初期設定やセキュリティ設定を設定する

  1. 一般的な初期設定やセキュリティ設定などを行います。
    • root ユーザのパスワードの設定
    • ホスト名の変更
      • /etc/sysconfig/network
      • /etc/hosts
      • hostname
    • 日本語設定
      • /etc/sysconfig/i18n
    • タイムゾーンの設定
      • /etc/cloud/cloud.cfg
      • /etc/sysconfig/clock
      • /etc/localtime
    • SSH の設定
    • iptables の設定
      • SSH
      • HTTPS

3.pysaml2 をインストールする

  1. 以下のリンクから zip ファイルをダウンロードします。

    wget https://github.com/rohe/pysaml2/archive/master.zip
    


  2. ダウンロードした zip ファイルを解凍し、解凍されたディレクトリに移動します。

    unzip master.zip
    cd ./pysaml2-master
    


  3. pysaml2 をインストールします。

    sudo pip install --upgrade pip
    sudo pip install repoze.who
    sudo yum install libffi libffi-devel
    sudo yum install gcc
    sudo python setup.py install
    

4.サンプルプログラムを起動する

  1. サンプルプログラムディレクトリに移動します。

    cd ./pysaml2-master/example
    


  2. 必要なライブラリをインストールします。

    sudo pip install mako
    sudo pip install "cherrypy==7.1.0"
    sudo yum install xmlsec1 xmlsec1-openssl
    sudo pip install pycryptodomex
    


  3. サンプルプログラムを実行します。

    ./all.sh start
    

    以下のメッセージが表示されたら、多分OK

    $ SP listening on localhost:8087
    $ IDP listening on localhost:8088
    

    サンプルプログラムを終了します。

    ./all.sh stop
    

5.外部接続用の設定をする

  1. iptables に以下の設定を追加します。

    -A INPUT -p tcp -m tcp --dport 8087 -j ACCEPT
    -A INPUT -p tcp -m tcp --dport 8088 -j ACCEPT
    
    sudo service iptables restart
    


  2. セキュリティグループ に以下の設定を追加します。 

    • TCP 8087 0.0.0.0/0
    • TCP 8088 0.0.0.0/0

  3. HTTPS 接続用に、適当な場所にサーバー証明書ファイル(公開鍵、秘密鍵)を格納します。

    • サーバー証明書の公開鍵 : *.cert
    • サーバー証明書の秘密鍵 : *.key

  4. 認証用の証明書を新たに作成します。

    ./create_key.sh
    
    Generating a new test key and certificate.  To change the defaults offered
    by openssl, edit your openssl.cnf, such as /etc/ssl/openssl.cnf
    
    Generating RSA private key, 1024 bit long modulus
    ..................++++++
    ...........++++++
    e is 65537 (0x10001)
    You are about to be asked to enter information that will be incorporated into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [XX]:JP
    State or Province Name (full name) []:[都道府県]
    Locality Name (eg, city) [Default City]:[市区町村]
    Organization Name (eg, company) [Default Company Ltd]:[企業名称]
    Organizational Unit Name (eg, section) []:
    Common Name (eg, your name or your server s hostname) []:[FQDN]
    Email Address []:[メールアドレス]
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:[パスワード]
    An optional company name []:[企業名称]
    Signature ok
    subject=/C=JP/ST=[都道府県]/L=[市区町村]/O=[企業名称]/CN=[FQDN]/emailAddress=[メールアドレス]
    Getting Private key
    
    Now to enable these new keys, do:
    
        cp server.key idp2/pki/mykey.pem
        cp server.crt idp2/pki/mycert.pem
    
        cp server.key sp-wsgi/pki/mykey.pem
        cp server.crt sp-wsgi/pki/mycert.pem
    

    作成した証明書をコピーします。

    cp server.key idp2/pki/mykey.pem
    cp server.crt idp2/pki/mycert.pem
    
    cp server.key sp-wsgi/pki/mykey.pem
    cp server.crt sp-wsgi/pki/mycert.pem
    


  5. サンプルプログラムを修正します。

    • ./pysaml2-master/example/idp2/idp_conf.py
    29c29
    < HOST = 'localhost'
    ---
    > HOST = '0.0.0.0'
    35c35
    <     BASE = "https://%s:%s" % (HOST, PORT)
    ---
    >     BASE = "https://%s:%s" % ("[FQDN]", PORT)
    37c37
    <     BASE = "http://%s:%s" % (HOST, PORT)
    ---
    >     BASE = "http://%s:%s" % ("[FQDN]", PORT)
    40,41c40,41
    < SERVER_CERT = "pki/mycert.pem"
    < SERVER_KEY = "pki/mykey.pem"
    ---
    > SERVER_CERT = "[サーバー証明書の公開鍵の相対パス]"
    > SERVER_KEY = "[サーバー証明書の秘密鍵の相対パス]"
    
    • ./pysaml2-master/example/sp-wsgi/service_conf.py
    4c4
    < HOST = 'localhost'
    ---
    > HOST = '0.0.0.0'
    20,21c20,21
    < SERVER_CERT = "pki/mycert.pem"
    < SERVER_KEY = "pki/mykey.pem"
    ---
    > SERVER_CERT = "[サーバー証明書の公開鍵の相対パス]"
    > SERVER_KEY = "[サーバー証明書の秘密鍵の相対パス]"
    
    • ./pysaml2-master/example/sp-wsgi/sp_conf.py
    18c18
    < BASE = "http://localhost:8087"
    ---
    > BASE = "http://[FQDN]:8087"
    21c21
    <     "entityid": "%s/%ssp.xml" % (BASE, ""),
    ---
    >     "entityid": "%s/%sp.xml" % (BASE, ""),
    


  6. サンプルプログラムを実行します。

    ./all.sh start
    


  7. 以下のサイトへアクセスし、ログインします。

    • http://[FQDN]:8087/
    • ログイン情報は、./pysaml2-master/example/idp2/idp.py (528行目) に記載。
    • daev0001 は、エラーになるので使わないこと!!

    FireShot Capture 46 - IDP test login_ - https___pysaml2.genbacloud.com_8088_sso_redirect.png

    FireShot Capture 45 -  - http___pysaml2.genbacloud.com_8087_.png

    サンプルプログラムを終了します。

    ./all.sh stop
    

6.pysaml2 側に連携用アカウントを設定する

  1. サンプルプログラムを修正します。

    • ./pysaml2-master/example/idp2/idp.py
    528a538
    >     "[メールアドレス]": "[パスワード]",
    
    • ./pysaml2-master/example/idp2/idp_conf.py
    37a38,60
    >     "[メールアドレス]": {
    >         "sn": "Testsson",
    >         "givenName": "Test",
    >         "eduPersonAffiliation": "student",
    >         "eduPersonScopedAffiliation": "student@example.com",
    >         "eduPersonPrincipalName": "test@example.com",
    >         "uid": "[メールアドレス]",
    >         "eduPersonTargetedID": "one!for!all",
    >         "c": "SE",
    >         "o": "Example Co.",
    >         "ou": "IT",
    >         "initials": "P",
    >         "co": "co",
    >         "mail": "mail",
    >         "noreduorgacronym": "noreduorgacronym",
    >         "schacHomeOrganization": "example.com",
    >         "email": "[メールアドレス]",
    >         "displayName": "Test Testsson",
    >         "labeledURL": "http://www.example.com/test My homepage",
    >         "norEduPersonNIN": "SE199012315555",
    >         "postaladdress": "postaladdress",
    >         "cn": "cn"
    >     },
    


  2. サンプルプログラムを実行し、サイトへのログインを確認します。

7.cybozu.com 側の設定をする

cybozu.com 側の設定は、以前の記事に同様の記載があるので、それを参考に行います。

  1. cybozu.com に SP の設定をする
    • SAML 認証を有効にする : ☑︎
    • Identity ProviderのSSOエンドポイントURL(HTTP-Redirect) : https://[FQDN]:8088/sso/redirect
    • cybozu.comからのログアウト後に遷移するURL : http://[FQDN]:8087/logout?goto=http://[FQDN]:8087/
    • Identity Providerが署名に使用する公開鍵の証明書 : 作成した証明書(server.crt)をアップロードします。
    • Service Providerメタデータのダウンロード
      • pysaml2 の SP の設定に必要なので、リンクをクリックしファイルをダウンロードしておきます。 (spmetadata.xml)

  2. cybozu.com に連携ユーザーを追加する
    • ※手順通り

8.pysaml2 側に cybozu.com の SP の設定をする

  1. ダウンロードした cybozu.com の Service Provider のメタデータ (spmetadata.xml) を適当な場所に格納します。

  2. サンプルプログラムを修正します。

    • ./pysaml2-master/example/idp2/idp.py
    48a49,50
    > from saml2.saml import NameID
    > from saml2.saml import NAMEID_FORMAT_TRANSIENT
    341a344,345
    >                 nameid = NameID(
    >                     format=NAMEID_FORMAT_TRANSIENT, text=identity["uid"])
    344a349,350
    >                     name_id=nameid,
    >                     sign_response=True,
    
    • ./pysaml2-master/example/idp2/idp_conf.py
    117c117,124
    <         "local": [full_path("../sp-wsgi/sp.xml")],
    ---
    >         "local": [full_path("../sp-wsgi/sp.xml"), full_path("[cybozu.com の Service Provider のメタデータの相対パス]")],
    >         #"inline":
    >         #"remote": [
    >         #    {"url": "",
    >         #     "cert": ""}],
    >         #"mdfile":
    >         #"loader":
    >         #"mdq":
    


  3. サンプルプログラムを実行し、cybozu.com のサイトへアクセスし、ログインを確認します。

pysaml2 のログイン画面からログインした後、 cybozu.com の画面が表示されたら、OK!!

99.ハマりポイント

  • まず pysaml2 のインストールですが、sudo python setup.py install を実行して、エラーが出たらログを確認しつつ、必要なライブラリを一つずつインストールしていく感じです。

  • サンプルプログラムの実行でも同様です。./all.sh start を実行しては、必要なライブラリのインストールをしていきました。
    • cherrypy は、7.1.0 じゃないとダメっぽいので、お気を付けを。
    • pycryptodomex は、pycryptodome じゃ無くて、pycryptodomex ですので、そこもお気を付けを。

  • で、やはりもっともハマったというか、よくわからなかったのが、「7.pysaml2 側に cybozu.com の SP の設定をする」のところでした。
  • ./pysaml2-master/example/idp2/idp.py がそのままだと、以下のエラーが表示され、

    FireShot Capture 48 - Assertion consumer service - https___3ejeh.cybozu.com_saml_acs.png

    create_authn_response の引数に sign_response=True, を追加して対処したら…

  • 次に以下のエラーが表示され、

    FireShot Capture 49 - Assertion consumer service - https___3ejeh.cybozu.com_saml_acs.png

    name_id=nameid, を追加して連携できた!!って感じででした。

  • どちらのエラーの時も、まずはログを見て、その後、./pysaml2-master/tests/ 配下のテストプログラムを確認したりしながら、修正していきました。SAML の仕様を理解しながらの対応だったので、時間が掛かりました。終わってみれば数行の追加でしたが…。

  • こちらのサイトも参考にさせて頂きました。

XX.まとめ

とりあえず、確認できて良かったです。
もう少し、SAML の仕様について理解を深める様、勉強しないといけないのかも…。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
9
Help us understand the problem. What are the problem?