ラベル ACS の投稿を表示しています。 すべての投稿を表示
ラベル ACS の投稿を表示しています。 すべての投稿を表示

2018年8月13日月曜日

サービス終了間際!Azure ACSの状況を確認する

こんにちは、富士榮です。

数年前に一世を風靡したAzure ACS(Access Control Service)ですが、いよいよ11月でサービス提供が終了されます。

ということで過去に作ったACSネームスペースの整理を進めようと思います。

しかし、旧Azure Portalが既にアクセスできず、現在のAzure PortalからはACSのWeb管理コンソールへのリンクがどこにもない、そして作ったネームスペースの名前も忘れている、という状態で途方に暮れているのは私だけではないはずです。

そういう人のためのPowerShellのモジュールがこちらです。

Acs.Namespaces
https://www.powershellgallery.com/packages/Acs.Namespaces/1.0.2


これを使うと、過去に作成したネームスペースの一覧の参照や有効化・無効化・削除などが可能です。

早速使ってみましょう。
手順に従いモジュールのインストールをしたら、まずは「Connect-AcsAccount」でACSに接続します。
ACSのログイン画面がポップアップするのでMicrosoft Accountでログインします。

次に、Microsoft Accountが紐づいているサブスクリプションを「Get-AcsSubscription」取得します。ACSのネームスペースはサブスクリプションに紐づいているので、サブスクリプションIDを指定して検索する必要があるためです。

サブスクリプション一覧が取得できたら、「Get-AcsNamespace」ネームスペースの状態を確認してみます。パラメータには先ほど取得したサブスクリプションのIDを指定します。

こんな感じでネームスペースと管理URLが取得できます。

ちなみに、しばらく放置していたACSネームスペースは無効化されているので、StateがDisabledになっているものは再度有効化しないと管理コンソールへログインできません。
たしかこんな名前のネームスペースがあったはずだけどアクセスできなくなってる・・・という人は無効化されている可能性があるので、確認してみてください。

ネームスペースを有効化するには、「Enable-AcsNamespace」を使います。


これで管理URLへアクセスすると懐かしのACSの管理コンソールが使えます。


昔作ったリソースの移行忘れが無いようにしておきましょう。

特に久しぶりに触るSharePointの実験環境など、私も忘れていたモノがあったのでACSからAzure ADへの切り替えをしておこうと思います。(ちなみにAzure ADでSAML1.1のトークンが発行出来ない問題は密かに解決しているので、既にACSが無くても直接Azure ADでオンプレSharePointのClaim Based Authenticationは使えるようになっています。手順などはまた紹介します)







2015年10月9日金曜日

[Azure AD]Azure AD B2Cを利用してソーシャル認証するアプリケーションを開発する

こんにちは、富士榮です。

先日Public Previewが公開されたAzure Active Directory B2C(Azure AD B2C)を使うと、これまでAccess Control Service(ACS)が担ってきたコンシューマ・アイデンティティ・プロバイダを使った認証をサポートするアプリケーションを開発することができます。

参考)
・公式Blogでの発表
 Azure AD B2C and B2B are now in Public Preview!
 http://blogs.technet.com/b/ad/archive/2015/09/16/azure-ad-b2c-and-b2b-are-now-in-public-preview.aspx

・安納さんによる世界一はやいまとめ資料
 https://docs.com/junichia/8538/azure-ad-b2c-preview-v0-6


ASP.NET IdentityやACSでも同じようなことが出来るので、今後どのようにすみ分けていくのかは要注目ですが、まずは手始めにOpenID Connectに対応しているものも、そうでないものも含め各種IdPをAzure AD B2Cを経由することによりOpenID Connect対応のIdPにすることができる、という点でアプリケーション開発者から見ると利点があると思われます。

早速、これまでAzure ADやAD FSのOpenID Connect対応を検証するために書いたコードをどこまで再利用できるのか?を確認してみたいと思います。

参考)過去のポスト
 [Azure AD]App Model v2.0を利用して組織内外共用のアプリケーションを開発する
 http://idmlab.eidentity.jp/2015/08/azure-adapp-model-v20.html

 [AD FS]OpenID Connectに対応した次期AD FSを試す
 http://idmlab.eidentity.jp/2015/08/ad-fsopenid-connectad-fs.html


◆OpenID Connect関連のパラメータを確認する
まずは、Azure AD B2CのOpenID Connect関連パラメータをwell-known/openid-configurationエンドポイントから覗いてみます。
エンドポイントアドレスは、
https://login.microsoftonline.com/{tenant}.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_signin
です。

{
  "issuer": "https://login.microsoftonline.com/xxxxxx/v2.0/",
  "authorization_endpoint": "https://login.microsoftonline.com/xxxx.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1_signin",
  "token_endpoint": "https://login.microsoftonline.com/xxxx.onmicrosoft.com/oauth2/v2.0/token?p=b2c_1_signin",
  "end_session_endpoint": "https://login.microsoftonline.com/xxxx.onmicrosoft.com/oauth2/v2.0/logout?p=b2c_1_signin",
  "jwks_uri": "https://login.microsoftonline.com/xxxx.onmicrosoft.com/discovery/v2.0/keys?p=b2c_1_signin",
  "response_modes_supported": [
    "query",
    "fragment",
    "form_post"
  ],
  "response_types_supported": [
    "code",
    "id_token",
    "code id_token"
  ],
  "scopes_supported": [
    "openid"
  ],
  "subject_types_supported": [
    "pairwise"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post"
  ],
  "claims_supported": [
    "emails",
    "sub",
    "idp"
  ]
}



これはマイクロソフトの悪い癖だと思うんですが、エンドポイントのアドレスにクエリパラメータをつけるのはちょっと頂けない感じですね。。。
実際にアプリケーションを開発する時にはConfiguration情報から取得したエンドポイントアドレスに他のパラメータをつけて処理を行うわけなので、クエリパラメータが2重についてエラーが起きてしまいます。。。
ここはAzure AD B2Cを使ったアプリケーション開発をする際の注意点ですね。


◆クライアント登録を行う
Azure AD B2Cの管理は新しいAzureポータルから行います。
このあたりの細かい設定方法は別の機会に紹介したいと思いますが、といあえずクライアント(アプリケーション)を登録してclient_idとclient_secretを取得しないと始まりませんので、まずは登録します。



◆アプリケーションを開発する
既存のOpenID Connect/RP(アプリケーション)のコードの再利用性を確認するのが目的なので、以前のポストで使ったPHPアプリケーションを再利用します。

完全互換であれば、
・authorization_endpoint
・token_endpoint
・client_id
・client_secret
・redirect_uri
を今回の環境に合わせて修正すればそのまま動くはずです。

早速修正してみました。


これで実行すると、、、404エラー来ました・・・。
先ほどのエンドポイントアドレスにクエリパラメータが入っているので変なエンドポイントへアクセスしてしまっています。
仕方がないので、認可エンドポイントへのGETリクエストのパラメータを'?'ではなく、'&'で連結します。



基本はこれで動くようになりましたが、id_tokenのフォーマットが微妙に違うようです。
具体的にはemailsクレームがマルチバリューで返ってくるので、jsonのパースをちゃんとしてあげないといけません。
例えばGoogle+だと以下のようなid_tokenがかえってきます。
{
  "exp": 1444322056,
  "nbf": 1444318456,
  "ver": "1.0",
  "iss": "https://login.microsoftonline.com/xxxx/v2.0/",
  "acr": "b2c_1_signin",
  "sub": "Not supported currently. Use oid claim.",
  "aud": "60a26a60-1c47-497c-b4c3-5cea0f1bc293",
  "iat": 1444318456,
  "auth_time": 1444318456,
  "idp": "google.com",
  "emails": [
    "xxx@gmail.com"
  ]
}



◆実行してみる
今回はGoogle+およびFacebookを使ってサインインする様にAzure AD B2Cを構成してみました。
それぞれの実行結果を確認してみます。

まずはアプリケーションへアクセスするとAzure AD B2Cのログイン画面へ遷移します。
デフォルト画面なので恐ろしくシンプルな画面です。
ここにあらかじめ設定しておいたアイデンティティ・プロバイダが出てきます。



初回アクセス時は認可の確認が求められますので許可すると、クレームが取得できます。
(ちなみに本当の初回はソーシャルIDでサインアップする必要があります。こちらの手順は別途紹介します)

Google+でサインインした場合



Facebookでサインインした場合




どちらの場合もsubが取得できないんですね。。。
今後にいろいろと期待です。


参考:今回利用したコード)
<?php

// パラメータ類
$authorization_endpoint = 'https://login.microsoftonline.com/xxxx.onmicrosoft.com/oauth2/v2.0/authorize?p=b2c_1_signin';
$token_endpoint = 'https://login.microsoftonline.com/xxxx.onmicrosoft.com/oauth2/v2.0/token?p=b2c_1_signin';
$client_id = '60a26a60-1c47-497c-b4c3-5cea0f1bc293';
$client_secret = 'xxxx';
$redirect_uri = 'https://xxxx.azurewebsites.net/index.php';
$response_type = 'code';
$state =  'hogehoge'; // 手抜き
$nonce = 'fogafoga'; // 手抜き

// codeの取得(codeがパラメータについてなければ初回アクセスとしてみなしています。手抜きです)
$req_code = $_GET['code'];
if(!$req_code){
    // 初回アクセスなのでログインプロセス開始
    // GETパラメータ関係
    $query = http_build_query(array(
        'client_id'=>$client_id,
        'response_type'=>$response_type,
        'redirect_uri'=> $redirect_uri,
        'scope'=>'openid',
        'state'=>$state,
        'nonce'=>$nonce
    ));
    // リクエスト
    header('Location: ' . $authorization_endpoint . '&' . $query );
    exit();
}

// POSTデータの作成
$postdata = array(
    'grant_type'=>'authorization_code',
    'client_id'=>$client_id,
    'code'=>$req_code,
    'client_secret'=>$client_secret,
    'redirect_uri'=>$redirect_uri
);

// TokenエンドポイントへPOST
$ch = curl_init($token_endpoint);
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($postdata));
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
$response = json_decode(curl_exec($ch));
curl_close($ch);

// id_tokenの取り出しとdecode
$id_token = explode('.', $response->id_token);
$payload = base64_decode(str_pad(strtr($id_token[1], '-_', '+/'), strlen($id_token[1]) % 4, '=', STR_PAD_RIGHT));
$payload_json = json_decode($payload, true);

// 整形と表示
print<<<EOF
    <html>
    <head>
    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
    <title>Obtained claims</title>
    </head>
    <body>
    <table border=1>
    <tr><th>Claim</th><th>Value</th></tr>
EOF;
    foreach($payload_json as $key => $value){
        if($key == "emails"){
            foreach($value as $mail_key => $mail_value){
                print('<tr><td>'.$key.'</td><td>'.$mail_value.'</td></tr>');                    
            }
        }else{
            print('<tr><td>'.$key.'</td><td>'.$value.'</td></tr>');            
        }
    }
print<<<EOF
    </table>
    </body>
    </html>
EOF;

?>

2015年6月6日土曜日

[Google/ACS]6/1を迎えてAzureACSのGoogle IDプロバイダーはどうなった

2015/04/20をもってGoogleのOpenID 2.0のサポートが終了し、マイクロソフトもAzure ACS(アクセス制御サービス)のGoogle IDプロバイダー設定を6/1までに変更するようにアナウンスを出していました。

関連ポスト)
 GoogleのOpenID 2.0サポート終了による影響いろいろ(Azure ACS編)
 http://idmlab.eidentity.jp/2015/03/googleopenid-20azure-acs.html

 [Google]4/20を迎えてAPIはどうなった?
 http://idmlab.eidentity.jp/2015/04/google420api.html


と、いうことで6月を超えたのでACSがどうなったのかを確認してみました。
結果、まだOpenID 2.0が動いています。結構しぶといです。
(人によって動いていない、という話もあるようなので環境に依存するのかもしれません)

これまで通りの動きです。
1.アプリケーションの認証の設定を行います。

2.実行するとレルムディスカバリ画面がでます。

3.Googleアカウントでログインします。

4.認可をおこないます。

5.アプリケーションからGoogleの属性が取得できています。




このように中々しぶとい状況ですが、MSDNには以下のアナウンスが出ています。
https://msdn.microsoft.com/ja-jp/library/azure/dn927169.aspx

2015 年 6 月 1 日 - ACS 名前空間は Google の OpenID 2.0 実装の使用を停止します。この日までに、ACS 名前空間の移行を完了して、Google OpenID Connect を使用する必要があります。この日までは、移行中に問題が発生しても、OpenID 2.0 にロールバックできます。
ほとんどの場合、アプリケーション コードの変更は必要ありません。アプリケーションに関連付けられているルール グループに ID プロバイダーとしての Google に対して "すべての要求をパススルーする" というルールが存在する場合は、コードの変更が必要になる場合があります。これは、移行によって Google からの新しい要求の種類 (サブジェクト) が ACS で利用可能になることから、アプリケーションが新しい要求の種類の存在を適切に処理できるようにコードを変更する必要が生じる場合があるためです。移行を正常に完了させるうえで、アプリケーションで新しい要求の種類を処理する必要はありません。
2017 年 1 月 1 日 - Google の OpenID 2.0 と OpenID Connect の実装では、Google ユーザーを一意に識別するのに、異なる識別子を使用します。ACS 名前空間の移行後は、現在の OpenID 2.0 識別子と新しい OpenID Connect 識別子の両方をアプリケーションで使用できるようになります。この日までにバックエンド システムでユーザーの識別子を OpenID Connect 識別子に切り替え、以降は OpenID Connect 識別子のみを使用する必要があります。これには、アプリケーション コードの変更が必要です。



ACS側の移行が終わっても次は2017/01/01までに従来のOpenID 2.0で使っていた識別子(nameidentifier)ではなく、OpenID Connectの識別子(subject)を使うようにアプリケーションの改修を行う必要があるようです。
ACS側でのクレームのマッピングを修正する形にしたほうが柔軟な気もしますので、私ならACSのクレームマッピング(規則グループ)を変えますが。。
※この図のnameidentifierとsubjectのマッピングを合わせてあげる形にします。既存アプリケーションはnameidentifier属性を見ているはずなので、OpenID Connect対応した際にGoogleから取得できるようになるsubject属性を出力側のnameidentifier属性にマッピングしてあげればアプリケーションを改修する必要はありません。


まだまだ余裕はありますが、こちらの改修も早めに実施しておいたほうがよさそうですね。

※使えなくなる瞬間どうなるのかを確認したいので、あえてACSの設定を移行せずに残してあるのですが、中々使えなくならないので、今後も引き続きウォッチしていきたいと思います。

2015年4月21日火曜日

[Google]4/20を迎えてAPIはどうなった?

# 2015/04/23現在
# ClientLogin : OK
# OpenID 2.0 : OK
# Provisioning API : NG - 503 Quota exceeded for the current request

GoogleのIdentityに関与している人なら少なからず気にしていた2015年4月20日を遂に迎えたわけですが、実際移行し忘れた人たちがどうなったのか、、、を確認してみたいと思います。

OpenID 2.0のサポート終了関連
 ⇒ Azure Access Control Services 2.0(ACS)

 関連ポスト)
  GoogleのOpenID 2.0サポート終了による影響いろいろ(Azure ACS編)
  http://idmlab.eidentity.jp/2015/03/googleopenid-20azure-acs.html

ClientLoginおよびProvisioning APIのサポート終了関連
 ⇒ Forefront Identity Manager(FIM)用のGoogle Apps管理エージェント(旧版)

 関連ポスト)
  [FIM]汎用REST管理エージェントをリリースしました
  http://idmlab.eidentity.jp/2015/03/fimrest.html


結論、4/21現在両方ともまだ使えました(笑)
(Azure ACSについては元々2015/6/1までは使える、と言っているので使えて当然ですが)


◆OpenID 2.0

ACSを使うサービスでログオンするとOpenID 2.0を使って認証しているのがわかります。


◆ClientLoginおよびProvisioning API

ClientLoginでGoogle Appsの管理者IDとパスワードを投げ込んでGoogle Auth Tokenを取得し、Provisoning APIへクエリを投げてユーザ一覧の取得が出来ています。





まぁ、いつ使えなくなってもおかしくないので早めに移行した方が良いですね。
(旧版のGoogle Apps管理エージェントのサポートがあるので、使えなくなったらどんな動きをするのか早く把握したい・・・)

2015年3月26日木曜日

GoogleのOpenID 2.0サポート終了による影響いろいろ(Azure ACS編)

いよいよ4月20日のGoogleのOpenID 2.0サポート終了まで1か月を切りました。


Googleのアナウンスページ
 https://developers.google.com/accounts/docs/OpenID

ちなみに今回終了するサービスにはOpenID 2.0だけではなく、Provisioning APIなども含まれるため、各IdM製品ベンダのGoogle Apps接続用コネクタは作り直しを余儀なくされたり、テレビに内蔵されているYoutubeアプリが使えなくなったり、、、と様々な影響が出ています。

個人的にも少々影響がありました。。。。

 昔作ったFIM用のGoogle Apps管理エージェントの作り直し
  過去のバージョン
   https://fim2010gapps.codeplex.com/
  作り直したバージョン(汎用REST API向け)
   https://restmafim.codeplex.com/

 自宅のTVのYoutubeアプリ終了
  http://www.sony.jp/info/20150123/


他にも、最近は全然使っていなかったので個人的にはあまり影響はありませんでしたが、OpenID 2.0を使っているサービスということで影響を受けるのが懐かしのAzure Access Control Service 2.0(ACS)です。
マイクロソフトも移行手順を公開したりメールで通知を送るなどして移行を促しています。
※こちらは何故か6/1までに移行するように、と書いてありGoogleの公式発表よりも少し猶予があります。何らかの調整が2社間であったのかも知れません。

 移行手順のページ(英語)
 https://msdn.microsoft.com/en-us/library/azure/dn927169.aspx

と、言うことで手順に従いマイグレーションをしてみました。
大まかにいうと、Google+ APIにアクセスできるクライアントをGoogle Developer Consoleで作成し、作成したクライアント情報(client_idとclient_secret)をACSに登録する、という手順です。

1.移行前の状態の確認

まずは、移行前の状態です。
ACSのIDプロバイダのページを開くと、昔作成したGoogle接続設定があります。


Googleを開くとクライアントIDとクライアントシークレットを設定出来るようになっています。


この状態でアプリケーションがACSを使うように構成すると、Googleを使ってログオンできる、という仕掛けなわけです。

アプリケーションの設定例)
Visual Studioでプロジェクトを作成する際にFederation Metadataを設定するだけなので、ノンコーディングでOKです。

IDプロバイダを選択

Googleアカウントでログイン

無事にログインし、ユーザ名が取得できます。


では、さっそく移行していきます。

2.クライアントの作成

Google Developer Console(https://console.developers.google.com/project)にログインし、プロジェクトを作成します。

[プロジェクトを作成]をクリックし、プロジェクト名などを適当につけます。



プロジェクトの作成が終わったら[APIと認証]の[認証情報]メニューを開き、[新しいクライアントIDを作成]をクリックします。
作成するアプリケーションの種類は「Webアプリケーション」を選択します。


途中、同意画面に関する情報を入力する画面が出ますが、適当にサービス名を入れておきます。



次に、JavaScript生成元、リダイレクトURIの指定が求められますので、それぞれ以下を設定します。
[承認済みのJAVASCRIPT生成元]
 https://[ACS名前空間].accesscontrol.windows.net:443
[承認済みのリダイレクトURI]
 https://[ACS名前空間].accesscontrol.windows.net:443/v2/openid

クライアントIDが正常に作成されると、クライアントIDとクライアントSecretが表示されるので、この2つの値をメモしておきます。(あとでACS側に設定します)


3.Google+ APIの有効化

Google Developer Consoleで作成したプロジェクトは初期状態でGoogle+ APIは無効状態なので、有効化しておきます。

APIの検索ボックスにGoogle+を入れてGoogle+ APIを探し、クリックします。

[Enable API]ボタンをクリックしてAPIを有効化します。

4.ACSにクライアントを登録する

これでクライアントの作成が終わったので、ACSに情報を登録します。
Use OpenID Connectにチェックをつけて、ClientID/Client Secretに先に取得した値を入れて保存します。


これで移行は終わりです。
※クレーム規則を定義していた場合は若干修正が必要になる場合があります。

5.動作確認

基本何も変わりません。
しかし、トレースするとOpenID Connectが使われていることがわかります。
Googleへのリダイレクト
GET https://accounts.google.com/o/oauth2/auth?client_id=xxxxxx.apps.googleusercontent.com&response_type=code&redirect_uri=https%3a%2f%2fxxxxxx.accesscontrol.windows.net%3a443%2fv2%2fopenid&scope=openid+email&openid.realm=https%3a%2f%2fxxxxx.accesscontrol.windows.net%3a443%2fv2%2fopenid&state=xxxxxxxxxxxx HTTP/1.1

code flowですね。
GET https://xxxxxx.accesscontrol.windows.net/v2/openid?state=xxxxxxxxxx&code=xxxxxxxxxx&authuser=0&num_sessions=1&session_state=xxxxx&prompt=none HTTP/1.1


参考までにOpenID Connectに変更する前の通信トレースはこんな感じです。
(こうやって見ると重たいプロトコルですねぇ。。)

GET https://www.google.com/accounts/o8/ud?openid.ns=http%3a%2f%2fspecs.openid.net%2fauth%2f2.0&openid.mode=checkid_setup&openid.claimed_id=http%3a%2f%2fspecs.openid.net%2fauth%2f2.0%2fidentifier_select&openid.identity=http%3a%2f%2fspecs.openid.net%2fauth%2f2.0%2fidentifier_select&openid.realm=https%3a%2f%2fxxxxx.accesscontrol.windows.net%3a443%2fv2%2fopenid&openid.return_to=https%3a%2f%2fxxxxx.accesscontrol.windows.net%3a443%2fv2%2fopenid%3fcontext%3dxxxxxxxxxx&openid.ns.ax=http%3a%2f%2fopenid.net%2fsrv%2fax%2f1.0&openid.ax.mode=fetch_request&openid.ax.required=email%2cfullname%2cfirstname%2clastname&openid.ax.type.email=http%3a%2f%2faxschema.org%2fcontact%2femail&openid.ax.type.fullname=http%3a%2f%2faxschema.org%2fnamePerson&openid.ax.type.firstname=http%3a%2f%2faxschema.org%2fnamePerson%2ffirst&openid.ax.type.lastname=http%3a%2f%2faxschema.org%2fnamePerson%2flast HTTP/1.1

GET https://accounts.google.com/o/openid2/auth?openid.ns=http://specs.openid.net/auth/2.0&openid.mode=checkid_setup&openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select&openid.identity=http://specs.openid.net/auth/2.0/identifier_select&openid.realm=https://xxxxx.accesscontrol.windows.net:443/v2/openid&openid.return_to=https://xxxxx.accesscontrol.windows.net:443/v2/openid?context%3Dxxxxxx&openid.ns.ax=http://openid.net/srv/ax/1.0&openid.ax.mode=fetch_request&openid.ax.required=email,fullname,firstname,lastname&openid.ax.type.email=http://axschema.org/contact/email&openid.ax.type.fullname=http://axschema.org/namePerson&openid.ax.type.firstname=http://axschema.org/namePerson/first&openid.ax.type.lastname=http://axschema.org/namePerson/last HTTP/1.1
GET https://accounts.google.com/o/openid2/auth?zt=xxxx&from_login=1&hl=ja&as=xxxxxx&authuser=0 HTTP/1.1

GET https://xxxxx.accesscontrol.windows.net/v2/openid?context=xxxxxx&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.mode=id_res&openid.op_endpoint=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fud&openid.response_nonce=xxxx&openid.return_to=https%3A%2F%2Fxxxx.accesscontrol.windows.net%3A443%2Fv2%2Fopenid%3Fcontext%3Dxxxx&openid.assoc_handle=xxxxx&openid.signed=op_endpoint%2Cclaimed_id%2Cidentity%2Creturn_to%2Cresponse_nonce%2Cassoc_handle%2Cns.ext1%2Cext1.mode%2Cext1.type.firstname%2Cext1.value.firstname%2Cext1.type.lastname%2Cext1.value.lastname%2Cext1.type.email%2Cext1.value.email&openid.sig=xxxxxx%3D&openid.identity=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid%3Fid%3Dxxxxxxxx&openid.claimed_id=https%3A%2F%2Fwww.google.com%2Faccounts%2Fo8%2Fid%3Fid%3Dxxxxxxxxxx&openid.ns.ext1=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0&openid.ext1.mode=fetch_response&openid.ext1.type.firstname=http%3A%2F%2Faxschema.org%2FnamePerson%2Ffirst&openid.ext1.value.firstname=Naohiro&openid.ext1.type.lastname=http%3A%2F%2Faxschema.org%2FnamePerson%2Flast&openid.ext1.value.lastname=Fujie&openid.ext1.type.email=http%3A%2F%2Faxschema.org%2Fcontact%2Femail&openid.ext1.value.email=xxxxxxxxx%40gmail.com# HTTP/1.1

ちなみに、ACSのIDプロバイダに新規でGoogleの設定をすると、Use OpenID Connectのチェックボックスが最初からチェックされており、外すことが出来ません。

今回のようにクラウド・サービスの仕様変更に伴い様々な影響が出ることを考えると、ますます自前で対応するのではなく、プロバイダ側で勝手に設定を変更してもらえるIDaaSなどのサービスを利用する方が良い、と言えるかも知れません。

2013年5月21日火曜日

[SharePoint]JPSPSフォローアップ:認証設定①~フォームベース認証

先日(5/18)に Japan SharePoint Group (http://jpsps.com/)さんの定例勉強会にお邪魔して SharePoint のアイデンティティ管理の話をしてきました。

当日の資料はこちら


当日は時間もなかったので、簡単なデモを見せることしか出来なかったので、環境の構築の方法について解説しておこうと思います。

まずは、認証の設定についてです。
当日はフォームベース認証と SAML トークンベース認証の2つのデモをお見せしましたが、今回はフォームベース認証について解説します。(Active Directory を LDAP の認証データベースとして利用します)

認証の設定を行い、実際にサイトを利用するには、大まかに以下の手順が必要です。
1.認証プロバイダの作成
2.Web アプリケーションの認証プロバイダの設定
3.Web アプリケーションのユーザーポリシーの設定
4.ユーザープロファイルとの紐づけ設定
5.動作確認 では順番に手順を解説します。

1.認証プロバイダの作成

 この手順では、SharePoint Server が認識する認証プロバイダを作成します。フォームベース認証の場合は、以下の3つの Web サイトの web.config ファイルの編集を行う必要があります。
  - サーバの全体管理(SharePoint Central Administration v4)
  - Security Token Service(SharePoint Web Services - SecurityTokenServiceApplication)
  - 対象の SharePoint Web アプリケーション(作成した名前)
   ※括弧内は IIS マネージャより見える Web サイトの名前

 IIS マネージャより上記それぞれの Web サイトに対応するフォルダを開き、 web.config を編集します。対象の Web サイトを右クリックしてエクスプローラを開いたところにある web.config が編集対象です。



 各 Web サイトの web.config を以下の用に設定します。

  - サーバの全体管理(SharePoint Central Administration v4)

  ・<system.web> セクションの以下をコメントアウト
    <roleManager>
      <providers>
      </providers>
    </roleManager>
    <membership>
      <providers>
      </providers>
    </membership>

 ・以下を追記
<membership defaultProvider="AspNetSqlMembershipProvider">
      <providers>
        <add name="LDAPMember"
             type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
             server="ADサーバ名.xxx.xxx"
             port="389"
             useSSL="false"
             userDNAttribute="distinguishedName"
             userNameAttribute="sAMAccountName"
             userContainer="OU=フォームベース認証するユーザを入れるOU,DC=xxx,DC=xxx"
             userObjectClass="person"
             userFilter="(ObjectClass=person)"
             scope="Subtree"
             otherRequiredUserAttributes="sn,givenname,cn" />
      </providers>
    </membership>
    <roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider" >
      <providers>
        <add name="LDAPRole"
             type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
             server="ADサーバ名.xxx.xxx" 
             port="389"
             useSSL="false"
             groupContainer="OU=フォームベース認証するユーザを入れるOU,DC=xxx,DC=xxx"
             groupNameAttribute="cn"
             groupNameAlternateSearchAttribute="samAccountName"
             groupMemberAttribute="member"
             userNameAttribute="sAMAccountName"
             dnAttribute="distinguishedName"
             groupFilter="((ObjectClass=group)"
             userFilter="((ObjectClass=person)"
             scope="Subtree" />
      </providers>
 </roleManager>

 - Security Token Service(SharePoint Web Services - SecurityTokenServiceApplication)

  ・<Configuration>セクションに以下を追記
<system.web>
    <membership>
      <providers>
        <add name="LDAPMember"
             type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
             server="ADサーバ名.xxx.xxx"
             port="389"
             useSSL="false"
             userDNAttribute="distinguishedName"
             userNameAttribute="sAMAccountName"
             userContainer="OU=フォームベース認証するユーザを入れるOU,DC=xxx,DC=xxx"
             userObjectClass="person"
             userFilter="(&amp;(ObjectClass=person))"
             scope="Subtree"
             otherRequiredUserAttributes="sn,givenname,cn" />
      </providers>
    </membership>
    <roleManager enabled="true" >
      <providers>
        <add name="LDAPRole"
             type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
             server="ADサーバ名.xxx.xxx"
             port="389"
             useSSL="false"
             groupContainer="フォームベース認証するユーザを入れるOU,DC=xxx,DC=xxx"
             groupNameAttribute="cn"
             groupNameAlternateSearchAttribute="samAccountName"
             groupMemberAttribute="member"
             userNameAttribute="sAMAccountName"
             dnAttribute="distinguishedName"
             groupFilter="(&amp;(ObjectClass=group))"
             userFilter="(&amp;(ObjectClass=person))"
             scope="Subtree" />
      </providers>
    </roleManager>
  </system.web>

 - 対象の SharePoint Web アプリケーション(作成した名前)

  ・<membership defaultProvider="i">の<providers>セクションに以下を追記

        <add name="LDAPMember" type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="ADサーバ名.xxx.xxx" port="389" useSSL="false" userDNAttribute="distinguishedName" userNameAttribute="sAMAccountName" userContainer="OU=フォームベース認証するユーザを入れるOU,DC=xxx,DC=xxx" userObjectClass="person" userFilter="(&amp;(ObjectClass=person))" scope="Subtree" otherRequiredUserAttributes="sn,givenname,cn" />

 ・<roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false">の<providers>セクションに以下を追記

        <add name="LDAPRole" type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="ADサーバ名.xxx.xxx" port="389" useSSL="false" groupContainer="OU=フォームベース認証するユーザを入れるOU,DC=xxx,DC=xxx" groupNameAttribute="cn" groupNameAlternateSearchAttribute="samAccountName" groupMemberAttribute="member" userNameAttribute="sAMAccountName" dnAttribute="distinguishedName" groupFilter="(&amp;(ObjectClass=group))" userFilter="(&amp;(ObjectClass=person))" scope="Subtree" />


2.Web アプリケーションの認証プロバイダの設定

 次は、Web アプリケーションに使用する認証プロバイダの設定を行います。
 [サーバの全体管理]から[Web アプリケーションの管理]を開き、対象の Web アプリケーションを選択し、[認証プロバイダー]を開きます。



認証プロバイダの領域では[既定]をクリックし、設定画面を開きます。



クレーム認証の種類のセクションで、[フォームベース認証(FBA)の有効化]にチェックを入れ、[ASP.NETメンバーシッププロバイダ名]に「LDAPMember(先ほど web.config に書いた名前)」、[ASP.NETロールマネージャ名]に「LDAPRole(先ほど web.config に書いた名前)」を設定し、保存します。





3.Web アプリケーションのユーザーポリシーの設定

 次は設定した認証プロバイダで認証されたユーザが Web アプリケーションへアクセスできるように設定します。
 先の手順と同様に[サーバの全体管理]から[Web アプリケーションの管理]を開き、対象の Web アプリケーションを選択し、[ユーザーポリシー]を開き、Web アプリケーションのポリシー画面で[ユーザーの追加]を開きます。



 対象の領域を聞かれるので[すべて]を選択し、[ユーザーの追加]画面の[ユーザーの選択]からユーザピッカーを開きます。


 [すべてのユーザー]から[すべてのユーザー(LDAPMember)]を追加し、元の画面に戻り、[権限の選択]で必要な権限を付与します。(画面は読み取り権限を与えています)




4.ユーザープロファイルとの紐づけ設定

 ここまでで認証とログインまでは出来るようになりましたが、SharePoint 上のユーザとの紐づけが出来ていません。つまり、認証とログインは出来ますが別途 User Profile Service 等で ID ストアから読み込んだユーザ情報と紐づけが出来ませんので、顔写真や姓・名などがうまく表示されない状態です。

 そこで、認証されたユーザと SharePoint 上のユーザプロファイルの紐づけ設定を行います。概念としては下図の通りです。



 今回作ったフォームベース認証プロバイダでは LDAP(AD)の sAMAccountName 属性を識別子として利用しているので、ユーザプロファイルの[クレームユーザーID]という属性が LDAP の sAMAccountName 属性の値と一致していれば同じユーザとみなす、という設定を行います。

 User Profile Service の詳しい設定については後日解説しますが、まず[サーバの全体管理]から[サービスアプリケーション]、[サービスアプリケーションの管理]、[User Profile Service Application]を開き、[ひと]セクションの[ユーザープロパティの管理]を開きます。
 この中の[クレームユーザーID]属性の編集を開きます。



 ここで認証プロバイダ LDAP の sAMAccountName をインポートするように設定し、保存します。



 この状態で[プロファイル同期の開始]で[完全同期]を行うと新しいマッピング状態を含めプロファイルが同期されます。  これで設定は完了です。


5.動作確認

 では、先ほどのサイトへアクセスしてみます。設定が上手く行っていればサインイン方法の選択が出来るようになっています。



 ここでフォーム認証を選択すると認証フォームが表示されますので、認証DB(今回は Active Directory)上に作成したユーザの sAMAccountName とパスワードでログインします。



 ちなみに Active Directory 上に作成したユーザは以下の通りです。



 認証がうまくいくとサイトが使えるようになっており、プロファイルには Active Directory 上に設定したユーザの情報が反映されているはずです。下図は Active Directory 上に顔写真を入れておき、SharePoint へ同期した例です。




今回はここまでです。次回は SAML トークンベース認証を Windows Azure Access Control Service と設定し、Facebook や Google アカウントでログインする方法を解説します。