SAML2.0エンドポイントをポリシーによって保護する話

本稿では、SAML2.0のエンドポイントへのアクセスをポリシーに基づいて制御する機能について説明します。これはコンソーシアム版OpenAM 14に含まれることになった新規機能です。
# 認証の方式や強度の指定

SAML2.0の仕様では、アサーションの発行時には認証が完了していることが前提です。認証そのものは脇役的な位置付けになっており、認証前後の動作に関わる部分が仕様の中心になっています。認証については、レベルや方式を認証コンテキストを使って指定できる程度に過ぎません。詳細については、[ここ](https://www.osstech.co.jp/_media/techinfo/openam/saml_authncontext_20150417.pdf)を参照してください。

この認証コンテキストに関する仕様はOpenAMを含む多くの処理系で実装されてはいるのですが、実際に効果的に使われているとは言えません。サービス提供者(SP)の側には、Identity Provider(IdP)を信頼しているので、どう認証するか細かな点はおまかせしたいという気持ちがあるように思われます。

こうした状況に対応するため、コンソーシアム版のOpenAMにアサーションを発行するためのエンドポイントをポリシーに基づいて保護する機能を追加しました。どのように認証されたユーザでどんな属性を持っているかをポリシーと照らし合わせ、条件が満たされているときにのみアサーションの発行を行います。

# メリット

サービス提供者(SP)側のメリットは明らかです。認証方式に関する細かなことを指定しなくても適切な認証方式がIdPによってSP毎に適用されるからです。提供するサービスの内容により厳密な認証が必要になる場合や厳密性よりもユーザの利便性が優先される場合等々、サービス提供者側の事情にあわせた細かな対応が可能です。また認証されたユーザが特定の属性を持つ場合に限りアサーションを発行する等々ができるようになります。例えば、ある特定の部署に所属する場合にのみアサーションを発行することが可能です。

ユーザにもメリットがあります。ポリシー条件を満たさないと判定された場合には、足りない部分の認証を追加で求めるようにすることが可能です。例えば、ユーザIDとパスワードで認証済みのユーザが、それに追加してワンタイムパスワードによる認証も必要とするサービス提供者のサイトにアクセスした場合には、差分であるワンタイムパスワードによる認証のみが求められるようになります。

# エージェントによる保護との比較

従来のエージェントによるURLの保護とは何がちがうのでしょうか。エージェントによる保護の機能では、ポリシーはURLもしくはURLの正規表現に対して定義しますが、エンドポイントの保護機能では、Identity Provider(IdP)のEntity IDとService Provider(SP)のEntity IDのペアに対して定義します。これにより単なるURLの保護と比較してより細かな設定が可能になります。

# 設定方法
設定方法について説明します。
## 機能の有効化
本機能はディフォルトでは無効になっています。有効にするために以下の手順を行ってください。

1. 管理コンソールを開き、連携タブ > 対象の IdP > 高度タブ に移動します
2. 「IDP アダプタクラス」に以下を設定します

`jp.co.osstech.oam.saml2.plugins.PolicyCheckIDPAdapter`

![enable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43512/21cf6bae-61dd-52d3-c2fd-1dd563b7d2df.png)

## ポリシーの定義
次にポリシーの定義方法について説明します。リソースタイプ、ポリシーセット、ポリシーの順に登録していきます。

### リソースタイプの登録
以下の項目を登録します

- 名前 : 任意の名前（ここではSAML2Endpointと指定） 
- パターン : idpEntityID=\*&spEntityID=\*
（末尾にスペースが入らないよう注意）
- アクション : IssueAssertion: 許可/拒否
（デフォルト値なのであとから変更可能です）

![resourceType.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43512/7d1597c0-94a1-34d5-4996-ad85511e6d4d.png)

### ポリシーセットの登録

「新規プロバイダポリシーセット」ボタンを押下します
![policySet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43512/1deac8a6-58b7-85c1-d327-f3cb795c81ad.png)

以下の項目を設定します：

- Id：SAML2ProviderService 
- 名前：任意の名前
- リソースタイプ： 上で登録したリソースタイプの名前(ここではSAML2Endpoint)
![policySet2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43512/85964622-a7b6-0f42-5f73-d902f2e86513.png)

### ポリシーの登録

以下の項目を設定します：

- 名前：任意の名前
- リソースタイプ：上で登録したリソースタイプの名前(ここではSAML2Endpoint)
- リソース：対象となるIdPとSPのEntity IDを設定

![newPolicy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43512/4ac56ec9-4198-fe7b-1686-b27a5851715f.png)

ポリシー条件の設定に関しては、エージェントを使った場合のURLポリシーと変わりありません。参考のために、ポリシー条件として設定できるものをリストしておきます。

- IP アドレス（範囲やDNS名）
- LDAPフィルタ条件
- OAuth2.0のスコープ
- グループへの所属
- アクティブなセッション時間
- モジュールインスタンスによる認証
- 認証連鎖による認証
- レルムへの認証
- 時間（曜日、日付、時刻）
- 現在のセッションプロパティ
- 認証レベル（以上）
- 認証レベル（以下）

例えば「時間」の条件を使えばアサーションは土日には発行しないといった設定も可能になります。さらにスクリプトを使ってより複雑な条件も記述できるようになっています。

# 認証コンテキストとの関係

認証コンテキストの指定がある場合にはそれを無視することはありません。認証コンテキストの条件が満たされた上でポリシーが満たされているかのチェックが行われます。

# OpenID Connect/OAuth2.0版

OpenID Connect/OAuth2.0のエンドポイントをポリシーによって保護する機能もコンソーシアム版のOpenAM 14で使用可能です。実は、OpenID Connect/OAuth2.0についてもSAML2.0とまとめてひとつの記事にしようしていたのですが、使用する用語が微妙に異なるため分かり難い内容になってしまいました。こちらについては別の記事を書きます。

[OpenID Connect/OAuth2.0用の記事](https://qiita.com/iwakata/items/b0a32935975faeea12cc)を書きました。