Skip to content

[scrap]SAML認証を実装した振り返り

公開日

概要

業務において、SAML認証の実装が必要となり、SP-InitiatedでIdP側を実装し、IdP-InitiatedでSP側を実装しました。 具体的な実装について尋ねられたため、改めて自身でも簡単に振り返っておきます。

実装方法

既存のPHPアプリケーションに組み込む必要があったため、lightSAMLを選択しています。

GitHub - lightSAML/lightSAML: SAML 2.0 PHP Library
SAML 2.0 PHP Library. Contribute to lightSAML/lightSAML development by creating an account on GitHub.
GitHub - lightSAML/lightSAML: SAML 2.0 PHP Library favicon https://github.com/lightSAML/lightSAML
GitHub - lightSAML/lightSAML: SAML 2.0 PHP Library

実装当時、SimpleSAMLphpという比較的多くの記事が存在するフレームワークも検証しましたが、何らかの理由により断念しました。 (既存システムのログイン処理に組み込むのが難しかったと記憶しています) lightSAMLはシンプルで理解しやすい構造で、ミドルウェア周りに手を加えることで要件に合致させることができました。 ただドキュメントは整備されていなかったため、試行錯誤の連続でしたが……

主にサイボウズのブログを参考にしつつ、lightSAMLの実装を解析・要件に合うように調整しました。

SAML認証ができるまで - Cybozu Inside Out | サイボウズエンジニアのブログ
こんにちは、Slashチームの渡辺です。 Slashチームでは、ユーザー管理や認証周りなどの、cybozu.comの各サービスに共通する機能を開発しています。今回は、3月にリリースされた、SAML認証を用いたシングルサインオン機能1についてお話させて頂きます。cybozu.comでのSAML認証の概要にくわえて、それらの機能をどのように設計・実装していったか、という誰も興味ないニッチな話題を扱います。
SAML認証ができるまで - Cybozu Inside Out | サイボウズエンジニアのブログ favicon https://blog.cybozu.io/entry/4224
SAML認証ができるまで - Cybozu Inside Out | サイボウズエンジニアのブログ

リリース後に近しい実装を行った記事がBaseで公開され、もう少し早く公開されていれば……と思いました。 ここまで細かく理解できていなかったので、参考になりました(ありがとうございます)。

IdPとしてSAML認証機能を自前実装した - BASEプロダクトチームブログ
はじめに みなさんはじめまして。BASEでエンジニアをしております田村 ( taiyou )です。 先日、BASEではショップオーナー向けのコミュニティサイト「BASE Street」にログインするための機能としてSSOログイン機能をリリースしました。 SSOログインを実現するための認証方式はいくつかあるのですが、弊社ではSAML認証方式を用いて実現しました。 そのため、この記事ではSAML認証機構のIdPとしてOSSを使わずにSAML認証機能を実装する方法を紹介します。 前回のテックブログで、このSSOログイン機能のフロント側を開発したPJメンバーの若菜が「サーバーサイドエンジニアがフロント…
IdPとしてSAML認証機能を自前実装した - BASEプロダクトチームブログ favicon https://devblog.thebase.in/entry/2022/10/03/180000
IdPとしてSAML認証機能を自前実装した - BASEプロダクトチームブログ

SAML連携について

仕組み

事前にシステム間で信頼関係を築くことが重要で、信頼関係がない場合は認証ができない仕組みとなっています。 この信頼関係は互いを証明する情報のやり取りによって実現します。 基本的にはメタデータのやり取りがベターですが、要件に含まれていなかったため手動でやり取りしました。

実装にあたっては特にアサーション(IdPでログインしたことをSPに伝える)のフローが理解しにくく、実装中に「今、自分は何の処理を作っているのだろうか?」と考えることが多かったです。 以下の内容を頭に入れておくと理解がスムーズかもしれません。 みんなここで苦戦しているのか、一見正しいと思われる記事が誤っている場合もあります(それもあって混乱しました)。


アサーションの署名

IdPはAssertionを生成し、自身の秘密鍵を使用してデジタル署名を行います。

アサーションの暗号化

IdPはSPの公開鍵を使用してAssertionを暗号化します。これにより対応する暗号鍵を所有するSPだけがAssertionを復号できる仕組みとなっています。

アサーションの送信

IdPはデジタル署名+暗号化されたAssertionをSPに送信します。

SPでの検証と復号

SPはIdPの公開鍵を使用して署名を検証し、成功した場合にはAssertionを自身の秘密鍵で復号します。


アサーションの中には任意の値を含めることができるため、ここにログインユーザの情報(メールアドレスなど)を付与することでSAMLログインが実現します。どの項目をログインに使用するかはSPとIdPの合意によるので、実際の案件では仕様を調整しながら実施しています。

SP-Initiated

SAMLRequestとRelayStateをIdPに渡して認証を行います。 「RelayStateは渡さなくても良い」という解説がありましたが、特に理由がなければセットで渡すのが無難です(なぜだったか思い出せませんが、RelayStateなしでは結局認証できなかったと記憶しています)。

IdP-Initiated

生成したSAMLResponseをSPに送り、SP側はSAMLResponseを解析するだけのため実装が比較的簡単。

まとめ

lightSAMLを使用した実装を通じて、SAML認証の仕組みを理解することができました。 簡単な振り返りでしたが、具体的な処理などは機会があれば追記したいと考えています。