シングルサインオン(SSO)でのSAMLとOAuthの概要と実装および相違点

機械学習技術 人工知能技術 セマンティックウェブ技術 オントロジー技術 検索技術 データベース技術 アルゴリズム デジタルトランスフォーメーション技術 Visualization & UX ワークフロー&サービス ITインフラ技術 クラウド技術 本ブログのナビ

シングルサインオン(SSO)

シングルサインオン(SSO)は、複数の異なるシステムやアプリケーションに対して、一度の認証を行うことで、ユーザーがそれらのシステムやアプリケーションにシームレスにアクセスできる仕組みとなる。これにより、ユーザーは複数のシステムに別々にログインする必要がなくなり、一度のログイン情報を使って、複数のシステムやアプリケーションにアクセスできるため、ユーザーの利便性が向上する。

SSOの仕組みは、通常、認証を担当する中央のシステム(認証サーバー)を介して行われる。ユーザーが最初に認証サーバーにログインすると、認証サーバーはユーザーを認証し、認証情報を発行する。その後、ユーザーは認証情報を使用して、複数のシステムやアプリケーションにアクセスすることができる。各システムやアプリケーションは、認証サーバーに認証を委任し、ユーザーの認証状態を確認するものとなる。

SSOの利点は、ユーザーの利便性向上、パスワードの管理簡素化、セキュリティの向上などがある。一度のログインで複数のシステムにアクセスできるため、ユーザーは複数のパスワードを覚える必要がなくなる。また、認証情報が一元的に管理されるため、セキュリティの向上やアクセス権の一元管理が可能になる。一方で、適切なセキュリティ対策を施さない場合には、一つの認証情報が漏洩した場合に複数のシステムにアクセスされるリスクもある。

SAML(Security Assertion Markup Language)

SAML(Security Assertion Markup Language)は、ウェブベースのSSOを実現するためのXMLベースの標準的な認証および認可フレームワークとなる。SAMLは、企業や組織が異なるドメイン間でユーザーの認証情報を共有するためのセキュリティ標準として使用されている。

SAML認証は、以下の主要なコンポーネントから構成されている。

  • サービスプロバイダ(SP): ユーザーがアクセスしようとしているアプリケーションやサービスを提供するプロバイダ。

  • イデンティティプロバイダ(IdP): ユーザーの認証情報を管理し、ユーザーが正当なユーザーであることを確認するプロバイダ。IdPは、ユーザーを認証し、SAMLアサーションと呼ばれるXMLドキュメントを生成してSPに送信する。

  • ユーザー: アクセスしようとしているアプリケーションやサービスを利用するユーザー。

SAML認証のフローは以下のようになる。

  1. ユーザーがSPにアクセスしようとすると、SPはユーザーをIdPにリダイレクトする。

  2. IdPはユーザーを認証し、SAMLアサーションを生成する。

  3. IdPは生成されたSAMLアサーションをSPに送信する。

  4. SPはSAMLアサーションを検証し、ユーザーを正当なユーザーとして認証する。

  5. 以上により、ユーザーはSPのアプリケーションやサービスにアクセスできるようになる。

SAMLには2つのパターンの認証の流れがある。(シングルサインオンでよく聞くSAML認証とは? 仕組みの概要、導入のメリットを解説!より)

  • SPを起点とするSP Initiatedの場合
    1. ユーザーがSPにアクセス
    2. SPがSAML認証要求を作成してユーザーに応答
    3. ユーザーはSPから受け取ったSAML認証要求をIdPに送信
    4. IdPの認証画面が表示される
    5. ユーザーはログインIDとパスワードを入力してIdPとの間で認証処理を行なう
    6. 認証が成功したらIdPからSAML認証応答が発行される
    7. ユーザーはIdPから受け取ったSAML認証応答をSPに送信
    8. SPにSAML認証応答が届くとログインできる

  • IdPを起点とするIdP Initiatedの場合
    1. ユーザーがIdPにアクセス
    2. IdPの認証画面が表示される
    3. ユーザーはログインIDとパスワードを入力してIdPとの間で認証処理を行なう
    4. 認証が成功したらIdPにログインできる
    5. IdPの画面からアプリケーションのアイコン(対象のSP)を選択
    6. IdP側でSAML認証応答が発行される
    7. ユーザーはIdPから受け取ったSAML認証応答をSPに送信
    8. SPにSAML認証応答が届くとログインできる

PythonによるSAMLの実装例

Pythonを使用してSAMLを実装するには、 python3-samlライブラリを使用することができる。以下は、 python3-samlライブラリを使用してSAML認証を実装する方法の概要となる。

  1. python3-saml ライブラリをインストールする。これは、pip install python3-samlを実行してインストールできる。

  2. SP (Service Provider) 用の設定を settings.py ファイルに追加する。これには、SPのエンティティID、証明書、プライベートキーなどが含まれる。

from saml2 import BINDING_HTTP_POST
from saml2 import entity
from saml2.config import Config
from saml2.sigver import get_xmlsec_binary

BASEDIR = "/path/to/saml/files"

config = Config()
config.load_file(f"{BASEDIR}/sp_conf.py")

sp = entity.SP(config=config)
  1. IdP (Identity Provider) からのSAMLレスポンスを受信するエンドポイントを作成する。
from flask import Flask
from flask import redirect
from flask import request
from flask import session

app = Flask(__name__)
app.secret_key = "secret_key"

@app.route("/saml/sso", methods=["POST"])
def saml_auth():
    authn_response = request.form["SAMLResponse"]
    # SAMLレスポンスの検証
    if sp.is_valid_response(authn_response, [BINDING_HTTP_POST]):
        # レスポンスが有効な場合の処理
        session["name_id"] = sp.get_nameid(authn_response)
        return redirect("/")
    else:
        # レスポンスが無効な場合の処理
        return "Invalid SAML response"
  1. SAML認証リクエストを生成して、IdPにリダイレクトする。
@app.route("/login")
def login():
    reqid, info = sp.prepare_for_authenticate()
    session["reqid"] = reqid
    redirect_url = None
    for key, value in info["headers"]:
        if key == "Location":
            redirect_url = value
            break
    return redirect(redirect_url)

実際のアプリケーションでSAMLを使用する場合は、さまざまなセキュリティ上の考慮事項に留意する必要があるため、十分なテストとセキュリティの対策が必要となる。

ClojureでのSAMLの実装

ClojureでのSAMLの実装には、 clj-samlライブラリを使用することができる。以下は、 clj-samlライブラリを使用してSAML認証を実装する方法の概要となる。

  1. clj-saml ライブラリをプロジェクトに依存関係として追加する。 project.cljファイルに以下の依存関係を追加することで行える。
[clj-saml "0.5.0"]
  1. SP (Service Provider) 用の設定を作成する。これには、SPのエンティティID、証明書、プライベートキーなどが含まれる。
(ns myapp.saml
  (:require [clj-saml.core :as saml]))

(def sp-settings
  {:entity-id "https://sp.example.com/metadata"
   :private-key "/path/to/sp-key.pem"
   :certificate "/path/to/sp-cert.pem"
   :acs-url "https://sp.example.com/acs"
   :single-logout-url "https://sp.example.com/logout"
   :nameid-format "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
   :force-authn false})
  1. IdP (Identity Provider) からのSAMLレスポンスを受信するエンドポイントを作成する。
(ns myapp.routes
  (:require [clj-saml.core :as saml]
            [ring.util.response :refer [redirect]]
            [ring.util.session :refer [update-session! get-session]]))

(defn saml-auth [request]
  (let [authn-response (-> request :params :SAMLResponse)
        session (get-session request)]
    ;; SAMLレスポンスの検証
    (if (saml/valid-response? sp-settings authn-response)
      ;; レスポンスが有効な場合の処理
      (do (update-session! session assoc :name-id (saml/get-nameid authn-response))
          (redirect "/"))
      ;; レスポンスが無効な場合の処理
      (str "Invalid SAML response"))))
  1. SAML認証リクエストを生成して、IdPにリダイレクトする。
(ns myapp.routes
  (:require [clj-saml.core :as saml]
            [ring.util.response :refer [redirect]]
            [ring.util.session :refer [update-session! get-session]]))

(defn saml-login [request]
  (let [session (get-session request)
        authn-request (saml/authn-request sp-settings)]
    ;; セッションにAuthnRequestを保存
    (update-session! session assoc :authn-request authn-request)
    ;; IdPにリダイレクト
    (redirect (saml/get-authn-request-url sp-settings authn-request))))
OAuth(Open Authorization)

OAuth(Open Authorization)は、異なるアプリケーション間での認可を実現するためのオープンスタンダードのプロトコルとなる。OAuthは、ユーザーがあるサービス(リソースオーナー)のリソースに対して、別のサービス(クライアント)が代理アクセスするための認可を取得するために使用される。

一般的に、OAuthはWeb APIなどのリソースを保護し、他のアプリケーションに対して安全な方法でアクセスを許可するために使用される。例えば、ユーザーが自分のTwitterアカウントを使ってあるアプリケーションにログインする際に、そのアプリケーションがユーザーのTwitterアカウントに代理アクセスするための認可を得る場合にOAuthが使用される。

OAuthは、認可プロセスを通じてアクセストークンというトークンを発行し、これを使ってクライアントがリソースオーナーのリソースにアクセスすることができる。OAuthには、バージョン1.0および2.0の2つのメジャーバージョンがあり、多くのプラットフォームで広く使用されている。

OAuthの主な利点は、ユーザーの認証情報を第三者アプリケーションと共有することなく、セキュアな方法でリソースにアクセスを許可できる点で、権限を制御するための細かいスコープ設定が可能であり、ユーザーのプライバシーを保護するための強力な仕組みを提供するポイントとなる。

Pythonでの実装例

PythonでOAuthの実装には、requests-oauthlib ライブラリを使用することができる。以下に、requests-oauthlibライブラリを使用してOAuth認証を実装するための基本的な手順を示す。

  1. requests-oauthlib ライブラリをインストールする。
pip install requests requests-oauthlib
  1. OAuth認証に必要な情報を取得する。これには、OAuthサービスプロバイダーから提供されるクライアントID、クライアントシークレット、承認エンドポイント、アクセストークンエンドポイント、リダイレクトURLなどが含まれる。

  2. OAuth2Session オブジェクトを作成する。これには、client_idclient_secretredirect_uriscopeなどが含まれる。

from requests_oauthlib import OAuth2Session

client_id = 'your-client-id'
client_secret = 'your-client-secret'
redirect_uri = 'http://localhost:8000/callback'
scope = ['scope1', 'scope2']

oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scope)
  1. 承認URLを取得して、ユーザーをOAuthサービスプロバイダーの認証画面にリダイレクトする。
authorization_url, state = oauth.authorization_url(authorization_endpoint)

print('Please go to %s and authorize access.' % authorization_url)

authorization_response = input('Enter the full callback URL: ')
  1. 認証画面からリダイレクトされたコールバックURLから、アクセストークンを取得する。
token = oauth.fetch_token(
    token_endpoint,
    authorization_response=authorization_response,
    client_secret=client_secret
)

実際には、各OAuthサービスプロバイダーによって異なる仕様があるため、より詳細な実装が必要になる場合がある。

Clojureでの実装

以前具体的なAuthの実装としては”マイクロサービスでのセキュリティ- ClojureでのAuthとPedestalを使ったAPI“にてClojureのPedestalを用いたものについて述べた。ここではもう少しシンプルな形態について述べる。

ClojureでOAuthの実装には、 clj-oauth ライブラリを使用することができる。以下は、clj-oauth ライブラリを使用してOAuth認証を実装するための基本的な手順となる。

  1. clj-oauth ライブラリを依存関係に追加します。以下の行を project.clj に追加する。
[clj-oauth "1.6.0"]
  1. OAuth認証に必要な情報を取得する。これには、OAuthサービスプロバイダーから提供されるクライアントID、クライアントシークレット、承認エンドポイント、アクセストークンエンドポイント、リダイレクトURLなどが含まれる。

  2. OAuthクライアントを作成する。これには、OAuthサービスプロバイダーから提供される情報を含め、clj-oauthライブラリの oauth-client マクロを使用する。

(require '[clj-oauth.client :as client])

(def oauth-client
  (client/oauth-client
    {:client-id "your-client-id"
     :client-secret "your-client-secret"
     :auth-url "https://oauth.example.com/authorize"
     :token-url "https://oauth.example.com/token"
     :redirect-uri "http://localhost:8000/callback"}))
  1. 承認URLを取得して、ユーザーをOAuthサービスプロバイダーの認証画面にリダイレクトする。
(require '[clj-oauth.core :as oauth])

(def authorization-url
  (oauth/authorization-url
    oauth-client
    {:state "some-state-param"
     :scope "scope1,scope2"}))

(println "Please go to " authorization-url " and authorize access.")
  1. 認証画面からリダイレクトされたコールバックURLから、アクセストークンを取得する。
(def access-token
  (oauth/fetch-access-token
    oauth-client
    {:grant-type :authorization-code
     :code "authorization-code"
     :redirect-uri "http://localhost:8000/callback"}))
参考図書

汎用的な参考図書としては「「Auth0」で作る! 認証付きシングルページアプリケーション」等がある。

本書を用いることで、簡単なwebページ用のAuth認証の実装を生部ことができる。内容は以下のようになる。

「Auth0」で作る! 認証付きシングルページアプリケーション 土屋 貴裕
	第1章 ウェブアプリケーションと認証
		1.1 モノリシックなアプリケーション
		1.2 モノリシックなアプリケーションとクッキー認証
		1.3 モバイルアプリケーションとトークン認証
		1.4 SPAと認証
		1.5 モダンなアプリケーションの構成とIdP
	第2章 トークンベース認証の基礎
		2.1 認証と認可
		2.2 OAuth2
		2.3 OpenID Connect(OIDC)
	第3章 JSON Web Token
		3.1 JWTとは何か?
		3.2 JWTの使い所
		3.3 JWTの構造
		3.4 暗号アルゴリズム
		3.5 APIへのリクエスト
		3.6 トークンの保存場所
		3.7 JWTHandbook
	第4章 Auth0
		4.1 Auth0とは
		4.2 Auth0のよい点
		4.3 名寄せ
		4.4 認証を丸投げする不安
		4.5 Auth0を使ってみる
	第5章 Nuxtで作るSPA
		5.1 Nuxt.jsとは
		5.2 Nuxt.jsを使ってみよう
		5.3 ビルド
	第6章 NuxtにAuth0を組み込む
		6.1 2種類のライブラリ
		6.2 Lockを組み込む
		6.3 トークンを管理する
		6.4 ログイン状態の判定
		6.5 Auth0APIへのアクセス
	第7章 NuxtとRailsを共存させる
		7.1 1つのリポジトリで管理する
		7.2 ディレクトリ構成の変更
		7.3 Railsの構築環境
		7.4 Rails New
		7.5 APIを作成してみる
		7.6 Nuxtの出力先を変更する
		7.7 開発時のProxyを設定する
		7.8 Proxyの動作確認
	第8章 RailsとKnockによる認証
		8.1 Knockとは
		8.2 Knockの導入
		8.3 鍵設定
		8.4 ユーザーの作成
		8.5 認証付コントローラーの作成
		8.6 認証必須なAPIを直接叩いてみる
		8.7 NuxtからAPIを呼び出す
	第9章 プロダクションビルドとデプロイ
		9.1 データベースの切り替え
		9.2 プロダクションビルド
		9.3 Auth0のセキュリティ設定
		9.4 ソーシャルアカウントのAPIキー設定
	第10章 設定のカスタマイズ
		10.1 複数のソーシャルアカウントログインを許可する
		10.2 パスワードログインを無効化する
		10.3 メールアドレスでログイン制限をかける
		10.4 名寄せを実現する
		10.5 トークンを更新する
	終わりに
SAMLとOAuthの違い

シングルサインオンを実現するという点ではSAML認証とOAuthは同じといえるが、両者の違いを理解するためのポイントは“認証”と“認可”の違いとなる。認証とはユーザーを証明するプロセスであり、認可はアクセスの権限を与えるプロセスとなる。SAML認証は認証と認可を行ない、OAuthは原則認証を行なわずに認可のみとなる。つまり、OAuthではAPIを利用する際に認証が行なわれていない、という点がSAML認証との大きな違いとなる。

もう少し具体的に述べると、SAMLとOAuthの主な違いは、使用目的とプロトコルの設計となる。SAMLは、異なるドメイン間での認証および認可を実現するためのXMLベースの認証プロトコルであり、SSOや組織間での信頼性のある認証を主に対象としている。一方、OAuthは、異なるアプリケーション間での認可を実現するためのプロトコルであり、Web APIなどのリソースを保護し、他のアプリケーションに対して安全な方法でアクセスを許可することを主に対象としているものとなる。

コメント

  1. […] シングルサインオン(SSO)とSAMLとOAuthの相違点 […]

タイトルとURLをコピーしました