2019年2月6日水曜日

[LINE Login]QRコードログインでメールアドレスもパスワードも不要に!

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

ついにLINE LoginがブラウザシナリオでのQRコードログインをサポートしました!
このことにより、LINEへのメールアドレスとパスワードの登録がない人でもPCのブラウザやスマホの標準ブラウザ以外でWebアプリへのLINEログインできるようになりました。
(永らく待ち望んでいた機能なのでとっても嬉しいです)

公式アナウンス
 https://developers.line.biz/ja/news/tags/line-login/


■従来の制限(ブラウザシナリオ)

従来もQRコードログインはPCやMac、iPad用のLINEアプリへのログインには使えていましたが、PCブラウザやスマホでも標準ブラウザ以外でLINE Loginを使ったWebアプリへアクセスすると、メールアドレスとパスワードを使ってログインする必要がありました。

もちろんスマホの場合はLINE Loginの自動ログイン機能が使える環境であれば、ブラウザからLINEアプリが呼び出されて自動的にログイン、ブラウザへ制御が戻る、という流れでメールアドレス・パスワードを使わないログインが実現できていました。

しかし、この自動ログイン機能はカスタムスキームを使ってLINEアプリを呼び出すところまではOKなのですが、標準以外のブラウザだとLINEアプリからブラウザへの戻す時に戻し先ブラウザの制御を行うことが出来なかったため、標準ブラウザの場合に制限されていました。
ということで、自動ログイン機能を使う場合は、以下の制限があります。
  • iOSの場合
  • LINE 7.5.0未満:アプリ内ブラウザで、LINEログインv2を実装したウェブサイトにアクセスすると、自動ログインできます。
  • LINE 7.5.0以降:アプリ内ブラウザまたはSafariブラウザで、LINEログインv2を実装したウェブサイトにアクセスすると、自動ログインできます。 
  • LINE 7.12.0以降:アプリ内ブラウザまたはSafariブラウザで、LINEログインv2またはv2.1を実装したウェブサイトにアクセスすると、自動ログインできます。 
  • Androidの場合
  • LINE 7.14.0未満:アプリ内ブラウザまたはChromeなどの外部ブラウザで、LINEログインv2を実装したウェブサイトにアクセスすると、自動ログインできます。 
  • LINE 7.14.0以降:アプリ内ブラウザまたはChromeなどの外部ブラウザで、LINEログインv2またはv2.1を実装したウェブサイトにアクセスすると、自動ログインできます。
  • 出典)https://developers.line.biz/ja/faq/


    ■QRコードログインが付かなかったことによる制限

    新規にLINEアプリを登録する時、SMSさえ通じればメールアドレスの登録は必須ではなく、パスワードも不要なため、スマホ・ネイティブな世代の殆どがメールアドレスもパスワードも登録しない状態でLINEの利用を開始していると思われます。
    もちろん、LINEもアカウントのリカバリの容易さなどを理由にメールアドレスとパスワードの登録を推奨していましたが、現実問題登録していないアカウントもそれなりの数、存在していました。(数字は言えませんが)

    上記の制限事項もあり、LINE Loginをブラウザシナリオで実装する際は、ある程度の数「使えない」ユーザが存在することを前提に設計を行う必要がありました。

    以前よりLINEさんにはブラウザでもQRコードログインをサポートしてもらえるようにお願いはしていたのですが、ようやく実現した!!というのが今回の発表です。

    ■早速使ってみる

    では、早速使ってみます。(といっても見た目は地味ですが)

    LINE Loginを使うWebサイトにアクセスするとLINEへリダイレクトされます。
    (ちなみに、QRコードログインを使うには、LINE Login v2.1を使っている必要があります)

    ログイン画面が変わっています。下の方に「QRコードログイン」がみえます!
    早速クリックすると、QRコードが表示されます。(一部マスクしています)

    おもむろにスマホを取り出してQRコードをスキャンします。
    (友達追加の時に使うアプリ内のQRリーダーを使います)

    ログイン確認をされるので、ログインボタンをタップします。
    すると、ブラウザに認証番号が表示されるので、スマホ側で数字を入力します。

    ここで入力します。


    問題なく確認が終わると、ブラウザ側でログイン処理が完了、アプリへ遷移します。



    ということで、メールアドレスもパスワードも使わずにアプリケーションへのログインができるようになりました!
    Microsoftアカウント、Yahoo! JAPANのパスワード・レス・ログインに続いてLINEも同体験を実現してきており、ようやく人類がパスワードを捨てることが出来る日がくる予感がしてきました。

    2019年2月4日月曜日

    Google+のサービス提供終了に伴うbloggerへの影響と本ブログにおける対応

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

    先日アナウンスされた通り、2019年4月でGoogle+のサービス提供が終了しますね。

    ご存知の通り、本blogはGoogleが提供しているbloggerを使っているので、何か影響があるのか調べてみました。
    結果、個人的にはそれほど大きな影響ではなさそうなので、放置することにします。

    ■Googleからの発表内容と本ブログへの影響

    2018年12月の発表、およびその後のメールなどによると、影響と対策は以下の通り。
    ※赤字部分が自身、本ブログに影響がありそうなところ
    ※今後アップデートがある可能性もあるので、一次ソースを見て対策をしてください。(本ポストの内容により影響が出ても責任はもてません)

    • 個人のGoogle+アカウントを持っている人、Google+ページを持っている人
      • 2019年2月4日
        • 新規にGoogle+プロフィール、ページ、コミュニティ、イベントの作成ができなくなる
        • 対策)特になし
      • 2019年4月2日
        • Google+アカウント、ページ等のコンテンツの削除を開始
        • 対策)コンテンツのダウンロードと保存をしておくこと(Googleフォトは消えないので大丈夫)
    • Google+コミュニティのオーナー、管理者の人
      • 2019年3月上旬〜
        • コンテンツのダウンロードと保存が可能になる
        • 対策)ダウンロードしておくこと
    • Google+ログインのボタンをサイトやアプリに配置している人
      • 今後数週間
        • ボタンが機能しなくなる(Googleログインのボタンが代わりに表示されることもあり)
        • 対策)ボタンの撤去。Googleログインのボタンが表示された人はそのまま使える(Googleアカウントでログイン)
    • Google+を使って自身のサイトや他のサイトへコメントを追加している人
      • 2019年2月4日
        • BloggerでGoogle+を使ったコメント機能は使えなくなる
        • 対策)他の機能でコメントする
      • 2019年3月7日
        • 他のサイトでGoogle+を使ったコメント機能は使えなくなる
        • 対策)他の機能でコメントする
      • 2019年4月2日〜
        • 既存のGoogle+で作成されたコメントが順次削除される
        • 対策)ダウンロードして保存しておくこと
    • G Suiteを使っている人
      • ビジネス向けGoogle+はサービス継続(新機能追加、デザイン変更あり)
      • ただし、G Suiteアカウントが外部Google+ユーザと共用しているページやコミュニティ、サークルなどについては一般向けGoogle+と同様に影響を受けるので対策は必要
      • 詳細はこちら
    • Google+ APIを使っている人(開発者)
      • 2019年3月7日
        • 全てのGoogle+ API(Google+ REST APIなど)が停止
        • Google+に関連するscope(例えば、plus.meやplug.login)を使った認可リクエストも受け付けられなくなるので注意

    ■本ブログにおける対応

    特に大きな影響はないので、基本方針は「放置」とします。

    一部影響があるのは以下。

    • プロフィール(私のプロフィール)
      • 対策)Bloggerプロフィールに戻します





    • コメントとリンク(そんなに使っている人もいないと思いますが)
      • Google+アカウントでのコメントは使えなくなります
      • 過去にGoogle+でコメントした人のコメントは消えます(特にこちらでバックアップ、どこかへ移行・公開はしません)
      • Google+への共有はできなくなります




    まぁ、大部分の方には影響ないですね。

    2019年1月31日木曜日

    Auth0でLINEログインを行う(メールアドレスの取得も)

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

    Auth0楽しいです。
    LINE Loginも楽しいです。

    と、言うことでAuth0を使ってLINE Loginを実装してみます。

    ちなみに、Auth0の古田さんが以前書いていらっしゃるQiitaを見ればそのままなんですが、メールアドレスが取れない!という課題が解決していないので、そのあたりもカバーしてみます。

    古田さんのQiita:Auth0でLINEログインを実装してみた(v2.1対応)
     https://qiita.com/furuth/items/6df4334c3821ffc69d9c

    ざっくり解説すると以下のとおり実装します。細かい手順は古田さんのQiitaを見てください。

    1. Auth0のExtensionの「Custom Social Connections」を使う(流石にLINEはビルトインされていない)
    2. LINE側に登録したClientID、ClientSecretをAuth0のExtensionに設定する
    3. Auth0のExtensionは基本的にOAuthなので、ユーザ属性はLINEのProfileエンドポイントから取得する

    LINEの場合、この3番が曲者ですね。
    以前、紹介したとおり、LINE Loginでメールアドレスを取得できるようにはなりましたが、あくまでid_tokenの中に入っており、Profileエンドポイントからは取得できないんです。

    以前のポスト


    と、言うことでAuth0のExtensionの中のプロファイル取得スクリプトでなんとかするしかありません。

    が、このプロファイル取得スクリプト、先に書いた通り、OAuthな前提なので、access_tokenを基にProfileエンドポイントへアクセスして属性を取得するようなサンプルしかありません。

    今回はここでid_tokenをとってきて中からメールアドレスを取り出したいので、以下のようにスクリプトを書き換えます。access_tokenは使いません。
    function(accessToken, ctx, cb) {
      var i = JSON.parse(jwt.decode(ctx.id_token));
      var p = {
        user_id: i.sub,
        name: i.name,
        picture: i.picture,
        email: i.email
      };
      cb(null, p);
    }
    

    ちなみに、LINEが返してくるid_token(JWT)はヘッダにtyp: JWTの記載がないので、node.jsのjsonwebtokenライブラリがうまくjsonオブジェクトに変換をしてくれず、stringで結果が返ってきてしまします。そのため、2行目でJSON.parseをつけてjsonオブジェクトに変換しています。
    ※Azure ADなどの場合はtyp: JWTがヘッダにあるので、JSON.parseは不要でした。jwt.decodeの第2引数にjson: trueってつけるとうまいことやってくれる、というドキュメントは見たことがあるんですが、今回は上手く動きませんでした
    ※場合によってjwt.decodeで怒られることがあるみたいなので、その場合は
     var jwt = require('jsonwebtoken');
     を追記してみてください。

    Tryボタンで動作確認ができ、ログインするとこんな感じでid_token内の属性が取得できます。

    ※(追記)スクリーンショットがわかりにくい(メールアドレスはTryでは出てこない)ので、ユーザ・プロファイルの画面を張っておきます。


    2018年12月25日火曜日

    TechSummitのおさらい④:Azure ADからSaaSアプリへのプロビジョニングのアレコレ

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

    引き続き、TechSummitのおさらいをしていきます。
    今回はAzure ADからSaaSアプリへのプロビジョニングの話しです。

    Azure ADからプロビジョニングできるアプリケーションの条件は以下の通りです。

    • ギャラリーに掲載されていてプロビジョニングに対応しているもの
    • SCIM2.0に対応しているもの

    現状(2018年12月現在)ギャラリーに掲載されているアプリは3,057個で、プロビジョニングに対応しているのは30個ですので、やはりプロビジョニングはハードルが高いですね。
    こちらが一覧です。


    サービス名
    Amazon Web Services (AWS)
    Asana
    BlueJeans
    Bonusly
    Box
    Cerner Central
    Cisco Spark
    Concur
    Cornerstone OnDemand
    DocuSign
    Dropbox for Business
    G Suite
    GitHub
    GoToMeeting
    Jive
    LinedIn Elevate
    LinkdIn Sales Navigator
    Lucidchart
    Netsuite
    Pingboard
    Salesforce
    Salesforce Sandbox
    Samanage
    ServiceNow
    Slack
    Tableau Online
    ThousandEyes
    Workday
    Workplace by Facebook
    Zendesk

    ここに記載がないアプリケーションの場合や自分で開発しているアプリケーションの場合は、SCIM2.0に対応していればある程度対応させることが出来ます。
    ちなみに、以前はSCIM2.0に対応している、かつ「Azure ADでSCIMのエンドポイントの保護をしていること=Azure ADが発行したアクセストークンで認可されること」という縛りがあったのですが、最近カスタムのアクセストークンでもアクセスできるようになりました。(Azure AD上へ固定で設定する必要があり、自動リフレッシュなどもできず微妙ですが)

    このシークレットトークンにカスタムのアクセストークンを指定します。指定しなければ従来と同じく、Azure ADで発行されたアクセストークンを使ってAPIへアクセスします。


    さて、本題です。
    TechSummitでは実際にプロビジョニングをやってみると起きる問題についてG Suiteとの連携を例に解説しました。

    もちろんすべてのアプリケーションで発生する問題ではありませんが、ざっくり言うと、

    • 複雑な同期ルールは設定できない(例えば、人事発令後7日以内は所属を新旧で兼務させる、などは無理)
    • プロビジョニング設定をしてテスト接続をして保存するとエラーが出てどうしようもなくなる(これはG Suite限定かもしれませんが)
    • 標準外の属性を定義してマッピングしても同期されない(これもアプリに依存)
    のような話があり、カタログスペック的にプロビジョニングに対応してるから使える!と思い込むと痛い目にあいます。

    すこし具体的な例とワークアラウンドを含め紹介していきます。

    プロビジョニング設定時にエラーが出てどうしようもなくなる件

    先にも書いた通り、G Suite限定かもしれませんが、プロビジョニング設定をして保存をした時にエラーが出ることがあります。しかも、このエラーが出てしまうと二度とプロビジョニング設定を行うことが出来なくなります。

    どうやら、既知の問題らしく、ワークアラウンドとしてSSO用のGSuiteとプロビジョニング用のG Suiteを分けて定義すると上手く動くんですが、アプリケーションへのユーザの割り当てなど結構面倒くさいです。


    追加属性のマッピングが上手く反映されない

    これも良くある質問で、アプリケーションの種類にかなり依存する話っぽいです。
    例えば、経験上ServiceNowなんかはある程度カスタム属性をマッピングしても動いてくれましたが、G Suiteは全くダメです。
    しかも、実環境でよく使われるOU(orgUnitPath)が上手くプロビジョニング出来ないのは致命的でgithubでも昔からissueが立っているくらいです。


    同じく、G Suite側で作ったカスタム属性も全く無視されちゃいます。


    では、どうするのか?

    使えないから諦められるのか?という話になりますが、Azure AD自体のプロビジョニング機能を使うのは、現状ある程度割り切った環境でないとあきらめた方がベターです。

    ということで、
    • Azure AD ConnectをMIM的につかう(カスタムMAを使う)
    • Azure FunctionとGraph API Subscriptionを使って自前プロビジョニングする
    の2択が現実的です。
    ※開発を伴うので、サポートをどうするかを含め熟考の上で使ってください。

    Azure AD Connectの魔改造

    まぁ、みなさんご存知のとおりAzure AD Connectの実体はMIM(Microsoft Identity Manager)です。しかもAzure AD ConnectにはSynchronization Rules Editorが付属しており、かなり優秀なので、MIMにもこのエディタをバックポートしてくれないかな、と本気で思います。

    話しがそれましたが、実体がMIMなのでMIM用に作ったカスタム管理エージェントを組み込むとほぼ何でもできます。


    ちなみに、MIMとAzure AD Connectではインストール時のフォルダ構成が異なるので、管理エージェントを後から組み込む場合はAzure AD Connectに合わせてバイナリを移動してあげる必要があります。

    後は、先のSynchronization Rules Editorで同期ルールを書けばうまく動くようになります。

    Graph APIのSubscriptionを使う

    別の方法はGraph APIのSubscriptionを使う方法です。
    SubscriptionとはAzure AD/Office365上のオブジェクトに特定のイベントが発生した時に外部のAPIへWebhookを飛ばす機能です。
    通常はOffice365のメールボックスにメールが配信されたら外部APIを叩く、などといった使い方をするのですが、Azure AD上のユーザに更新がかかったら変更内容を通知する、という使い方をすることでプロビジョニングに応用できます。
    ちなみにプロビジョニング処理自体はAzure Function等を使って完全に自前で実装することになります。

    Subscriptionを作成する際もGraph APIを使います。
    対象のリソース(users)と検知対象のアクション(updated)、Webhook通知先URLを指定してSubscriptionを作成します。

    尚、現状だと検知対象のアクションとしてcreatedやdeletedを指定するとエラーが出るのでupdatedしか使えません。作成と削除はAzure ADのプロビジョニング機能を使い、更新はSubscription経由で実施する、という構成にしないといけません。

    ちなみに作成したSubscriptionオブジェクトの有効期限は最大3日間なので、期限が切れる前に更新をしないと自動的に削除されてしまいます。


    Subscriptionが有効な状態でユーザオブジェクトに更新がかかると指定したURLに対してWebhookが飛んできます。
    この内容をパースして適切な処理を行いましょう。G Suiteの場合はAdmin SDKを使ってG Suite上のユーザの属性を更新する、などの処理ですね。



    今回はこのくらいです。
    プロビジョニングは結構鬼門なので、使う場合は十分に事前調査~準備をしてから使い始めるようにしてください。

    2018年12月21日金曜日

    TechSummitのおさらい③:Azure AD + Auth0 で条件付きアクセスを構成する

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

    そろそろディープになってきました。公式イベントで話すにはかなり気が引けるネタ度Maxです。

    今回はAuth0(おーすぜろ)とAzure ADを組み合わせることで複雑なことをやろう!という話です。

    もちろんAzure ADにはPremium P1/P2という複雑なことをやりたい人向けのプレミアなライセンスがありますので、お金に余裕のある方、一気通貫でサポートを頼みたい方は迷わずそちらを選んでください。

    Auth0とは?

    Auth0もMicrosoftやOkta、PingIdentity、OneLoginなどと同様にIDaaS(Identity as a Service)を提供しているサービスプロバイダです。jwt.io辺りで有名ですね。
    ちなみにFounderは元マイクロソフトのEugenio Paceです。「A Guide to Claims-Based Identity and Access Control」をVittorio Bertocciと一緒に書いた人ですね。まだ彼がMSにいる時代にやり取りをしてサイン本をもらったりしたもんです(遠い目)。最近は共著のVittorioもAuth0へ移ったのが個人的なビッグニュースでした。

    少し特徴的なのは「開発者向け」である、という売り出し方をしているところですね。開発者向けたる所以は、ひたすらかゆいところに手が届くから、というのが最大の理由だと思います。

    このAuth0、実は別のサービスとしてWebtaskというFaaS(Function as a Service)を提供しており、ID関連の機能の各所にこのWebtaskをどんどん差し込んでいくことが出来るんです。このことにより、例えばid_tokenの中身を見て処理を実行したり、ID登録直後に別の処理を走らせたり、など開発者がやりたい放題出来てしまいます。


    Azure AD + Auth0?

    さて、Azure ADとAuth0を組み合わせると何が出来るのか?という話に移りたいと思います。
    Auth0はAuth0自体にIDを保持して自身がIdPとして振舞う以外に、外部のIdP(Connectionと呼んでいます)とID連携する機能を持っています。また、当然のごとく外部のSPとID連携することもできます。
    このことを使い、IDの保持とベーシックな認証機能はAzure ADで、複雑な処理(今回は条件付きアクセスと多要素認証)はAuth0で担当、というようなことを実現することが出来ます。
    使えるプロトコルも多様なので、アプリ(今回はG Suite)とAuth0の間はSAML、Auth0とAzure ADの間はOpenID Connect、という構成を組んでみました。


    Azure ADのアプリ(RP)としてAuth0を登録

    早速構成していくわけですが、まずはAuth0の外部IdPとしてAzure ADを構成するためには、Azure ADのRelying Party(RP)としてAuth0を登録してあげる必要があります。具体的には、ReplyUrl(応答URL)にAuth0のエンドポイント(Callback)を登録し、Auth0側に設定するためのClient IDとClient SecretをAzure ADから払い出します。

    Azure ADのアプリ登録メニューより登録を行います。
     Azure ADに登録するAuth0のCallback URLは以下の通りです。
      https://{テナント名}.auth0.com/login/callback


    Auth0の外部IdPとしてAuth0を登録

    次は、逆側の設定なので、Auth0にAzure ADの情報を登録していきます。
    ちなみにAuth0はビルトインのConnectorとしてAzure ADが用意されているので、こちらを使ってもいいですし、OAuthを使ってカスタム接続するためのExtensionもあるのでこちらを使って接続しても問題はありません。

    こちらがビルトインのAzure ADとの接続Connector

    こちらがOAuthを使うExtension


    私は後者のExtensionを使っています。(というかビルトインでAzure ADが存在しているのを知らなかった・・・)
    Azure ADの認可エンドポイント、トークンエンドポイントと先ほどアプリ登録した際に取得したClient IDとClient Secretを登録します。

    ちなみに、例のWebtaskを使ってGraph APIでAzure AD上のユーザ情報を取得することが出来ます。SAML Assertionに属性を入れてアプリに渡す必要があるので、必要な属性を取得する様にスクリプトを作ります。
    function(accessToken, ctx, cb) {
    
      request.get('https://graph.microsoft.com/v1.0/me', {
          headers: {
            'Authorization': 'Bearer ' + accessToken,
          },
          json: true
        },
    
        function(e, r, u) {
          if (e) return cb(e);
          if (r.statusCode !== 200) return cb(new Error('StatusCode: ' + r.statusCode));
          var profile = {
            user_id: u.userPrincipalName,
            name: u.displayName,
            email: u.mail
          };
          cb(null, profile);
        });
    }
    


    直観的にわかりやすいスクリプトだと思うので、あまり解説する必要もないとは思いますが、トークンエンドポイントから取得したアクセストークンがコンテキストとコールバック先のオブジェクトと一緒に渡ってくるので、Graph APIにアクセスして必要な情報を取得、Profileとして設定して返却してあげる、という流れです。

    G SuiteとAuth0をID連携

    ここはこれまで何度となく解説してきたG Suiteのシングルサインオン設定の世界なので、G Suite側は目をつぶっていても構成できてしまう世界だと思いますので、Auth0側の設定を中心に。

    ちなみにAuth0にはApplicationギャラリー的なプリセット・アプリのリストは存在しません。めちゃくちゃシンプルにNative App、SPA、Regular Web App、Machine to Machine Appの4種類しかありません。

    G Suiteなど通常のアプリを使う場合はRegular Web Appを選びましょう。

    また、Regular Web Appを選んだとしてもデフォルトではアプリと言っても単純なOAuthのクライアント登録しか出来ないので、AddOnという形でSAML等のプロトコルを設定してあげる必要があります。
    SAMLの設定もかなりプログラマブルなので、Assertion内の各種パラメータをガリガリと書いていきます。本当に痒い所に手が届きます。ほぼ出来ないことは何もないので、Assertionの書き方の方言でうまくアプリと繋がらない、というトラブルとは無縁だと思います。その代わりSAML Assertionの中身の仕様について熟知している必要はありますが。


    この構成のページからIdP MetadataやAssertion署名用の証明書のダウンロードなども可能なので、エンドポイントや証明書をG Suite側に設定してあげれば完了です。

    これで一通り単純なシングルサインオンについて出来るようになっています。


    条件付きアクセスを構成する

    ここまでだとAuth0がG SuiteとAzure ADの間に挟まっている必要性が全くないので、最初に書いた通り、条件付きアクセスを構成してみます。
    本来Azure ADではPremium P1のライセンスが必要な機能です。

    Auth0での条件付きアクセスを構成するには、Rulesメニューよりルールを構成します。
    このルールもJavascriptでガリガリと書いていくことが出来るので、ものすごく柔軟です。アクセス元の状態はContextから取得できるので、ソースIPやUser Agentなど様々な情報を見て多要素認証の適用の有無など各種条件を設定することが可能です。
    function (user, context, callback) {
      const ipaddr = require('ipaddr.js');
      // 社内ネットワーク
      const corp_network = "x.x.x.x/16";
      // 対象のアプリケーションのclient_id
      const CLIENTS_WITH_MFA = ['G SuiteのClient Id'];
    
      // 接続元のソースIP
      const current_ip = ipaddr.parse(context.request.ip);
      if ((!current_ip.match(ipaddr.parseCIDR(corp_network)) && (CLIENTS_WITH_MFA.indexOf(context.clientID) !== -1))) {
          context.multifactor = {
            provider: 'google-authenticator',
            allowRememberBrowser: false
          };
      }
    
      callback(null, user, context);
    }
    


    ここまで構成すると社内アドレス以外からG Suiteを使おうとすると多要素認証(今回はGoogle Authenticator)を要求される様になります。



    こんな感じでAzure AD+Auth0で見た目はぼぼAzure AD Premiumの条件付きアクセス、ということが実現できてしまいました(笑)。

    まだまだネタは続きます。では次回!

    2018年12月19日水曜日

    TechSummitのおさらい②:Azure ADとSaaSアプリのSSO構成時のトラブルシュートあれこれ

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

    前回に引き続きTechSummitのフォローアップです。

    今回は2つ目のネタ「SaaSアプリのSSO構成時のトラブルシュートあれこれ」についてです。

    簡単に言うと、同じ種類のSaaSアプリを複数インスタンス(例えば本番環境と開発環境とか)を単一のAzure ADとSSOの構成をしようとすると動きがおかしくなる「ことが」ある、というお話しです。

    よくあるシーンはこんな感じで、本番・開発の2環境を用意したいけど、Azure ADってテナント毎、ユーザ毎のライセンスなので出来ればAzure ADは単一の環境で済ませたいよね、っていう話です。

    TechSummitでは個人的な経験を基に、G Suiteを複数インスタンス用意してSSOを構成しようとしたとき、たまに発生する問題を紹介しました。
    ※ちなみにSalesforceでも起きることがあるようですが、すべてのアプリで発生するわけではありません。また、G Suiteでも毎回起きるわけではありません。

    何が起きる(た)のか

    先ほど書いたように、毎回起きるわけでもなく、発生条件も良くわからない状態なので、ここに書いたことが必ず起きるわけでもなく、他に発生する問題がある可能性もありますが、とりあえず私が体験したことを書いていきます。

    • NameIDの値のマッピングが上手くいかない(UPNを使ってくれない)
    • SP EntityIDが一致していない、と言われる


    NameIDのマッピング不良と対策

    まずは前者です。
    初期状態のAzure ADはG SuiteのSSO構成時、NameID属性としてuserPrincipalName属性をマッピングします。また、G SuiteのNameID Formatの指定はunspecifiedです。

    通常、この構成だとAzure ADはuserPrincipalNameの値をそのままG Suiteへ渡すのですが、なぜか仮名が生成されてNameIDとして渡されてしまうことがあります。通常はNameID FormatがTransientやPersistent以外は仮名が生成されることは無いはずなのですが、何かがおかしいです。


    これを解消しようとすると、Azure AD側のでNameID Formatを明示的に指定してあげる(つまり、G Suiteからの指定を無視する)必要があります。
    G Suiteはメールアドレス形式でNameIDの値が飛んでくるのを期待しているので、NameID Formatをemailaddress(電子メールアドレス)にしてあげます。


    これでうまくいきます。


    SP EntityIDの不一致

    次に、SSOを試みた時に出てくる「AADSTS65005: Misconfigured application」エラーへの対策です。このエラーはAzure AD側でアプリケーション構成がおかしいので見直せ!というエラーです。


    最近はAzure ADのSSO構成も人にやさしくなっており、エラーの詳しい原因が管理ポータルからある程度確認できるようになっています。(Salesforceが昔から実装していた機能ですね)
    これまでSAMLのやり取りをトレース&解析しないとダメだったのですが、この機能が出来てかなり楽になりました。

    この機能を使って先のエラーの原因を探ると、なぜかSP EntityID(要するにアプリケーションを一意に識別する情報)がマッチしていない、と言われます。どう見ても一致してるんですが・・・
    もちろんアプリケーションが一つしか構成されていない状態ではこのようなことは言われないのですが、G Suiteを複数インスタンス構成するとタマにこのエラーが出ます。
    ※ちなみに昔はもっとひどかった(構成するとユーザの割り当てが混ざったりしていた)ので、マシにはなったんですが・・・


    実はこのエラーが出ると、Azure AD側ではどうしようもなく、強引に複数のG Suiteインスタンス間でEntityIDが絶対に重複しない様に構成を工夫するしかなくなります。
    今回やったのは、片方のG Suiteについて、Google側でEntityIDにドメイン固有情報を含めるのを辞める、という苦肉の策です。
    これで複数のG Suiteインスタンス間で必ず異なるEntityIDが使われるようになるので、問題が解決します。(本来はこんなことをしなくても必ず異なるEntityIDは使われるんですが)



    まぁ、今回紹介したものは発生することもある、というレベルなので仕組みを理解した上で適度に使ってもらえれば、というレベルの話でした。

    引き続きフォローアップをしていきますので、お楽しみに。


    2018年12月17日月曜日

    TechSummitのおさらい①:Azure ADで非SSLアプリとのSSOを構成する

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

    ようやく秋口からのセミナーラッシュが落ち着いてきたので、先日のTechSummitでお話しした非公開ネタを解説していきたいと思います。

    内容的にマイクロソフトの公式イベントでお話しするにはあまりにも非サポートだったり、別の会社の製品との組み合わせを紹介しすぎたり、と大人の事情満載だったので当日は撮影禁止&資料・動画公開なしとさせていただいたネタです。

    当日お話しした内容は公開可のモノも含めると以下の通りです。


    1. 非SSLな開発環境とSSOを構成したい!
    2. SaaSアプリとのSSO時のトラブルシュートあれこれ
    3. Azure AD Premiumは買えないけど複雑なことをやりたい
    4. SaaSアプリへのプロビジョニングがちょっとアレな話
    5. マルチフォレストのオンプレADとの同期すときのあれこれ
    6. マルチフォレスト構成時のパスワード同期元/先を制御したい!

    と、言うことで順番に解説していきたいと思います。
    今回は1番目の「非SSLな開発環境とSSOを構成したい!」です。

    Azure ADがSSOを構成するアプリはSSLじゃないとダメ!?

    すでにAzure ADをお使いの方はご存知だと思いますが、Azure ADを使ったアプリとのSSOを構成するには、アプリをSSL化しておくことが前提となります。
    この時に困るのが、開発環境をどうするか?という話です。もちろん余裕のある方は開発環境を含めてSSL化しておくことも可能でしょうし、最近はLet's Encryptなど無償の証明書を発行してくれる機関もあるので、こちらを活用して行くことも可能なのでニーズは減ってきていると思いますが、やはり面倒ということもあり何とか手軽に非SSLな開発環境でもSSOを構成していきたいところです。
    ※もちろん非SSLな環境を推奨している訳ではありませんので誤解なきよう。。。

    非SSLなアプリを構成しようとすると何が起きるか?

    先ほど、標準のAzure ADだとアプリのSSL化が前提となっている、という話をしましたが、具体的に何が起きるのか?を先に説明しておきます。
    といっても単純にSAMLアプリの場合はAssertion Consumer Service(ACS)、OpenID Connectアプリの場合はReply URIを設定する際にhttpsスキーム以外だと怒られて設定が出来ない、というだけです。


    ここで、考えるべきなのは
    • このエラーはUI上でのValidationの問題なのか?
    • それともデータを保存する際のValidationの問題なのか?
    ということです。

    個人的な経験からすると、Azure ADの構成情報の実体データは割りと素な状態でストアされており、管理者はPowerShellやAPI(そしてオマケとして管理ポータル)で設定を行うという構造になっていますので、今回についてもACS/ReplyURIの元データを何とかして修正できれば目標を達成できるはず、と考えました。

    Azure ADにおけるアプリ登録情報の実体

    ということで、管理ポータルの存在は一旦忘れて登録されたアプリケーションの構造を生データで見ていきましょう。
    まずは一番単純な方法としてPowerShellを使います。※ここは時間の関係でTechSummitでもお話ししなかった部分です。

    Azure Active Directory Module for Windows PowerShellを使いますので、インストールしていない人は「Install-Module -Name AzureAD」あたりで先にモジュールをインストールしておいてください。

    取り敢えず「Connect-AzureAD」でAzure Active Directoryへ接続しましょう。
    次に登録済みアプリケーションの情報を確認するために「Get-AzureADApplication」を実行します。

    登録されているアプリがずらりと出てきます。


    この中から、構成をしたいアプリケーションを見つけて、ObjectIDを指定して再度「Get-AzureADApplication」を実行して構成情報を確認します。この時、パイプでflをつけると細かいパラメータが見えます。
    こんな感じです。
    「Get-AzureADApplication -ObjectId xxxxx | fl」

    その中にReplyUrlsというパラメータが見えます。

    SAMLだろうがws-federationだろうがOAuthだろうがOpenID ConnectだろうがReplyUrlsです。潔すぎです。
    この値がSAMLの場合はACSのURL、ws-federationの場合はwreply、OAuth/OpenID Connectの場合はReplyURIですね。

    PowerShellを使って値を変えてみる

    アプリの構成を取得するときに使ったのが「Get-AzureADApplication」なら構成を変更するときに使うのは「Set-AzureADApplication」です。

    ただ、このReplyUrlsは配列で値が入るので、セットしたい値は配列としてセットします。PowerShellの場合は「@("値1","値2")」という形式が必要です。

    ということで、
    「Set-AzureADApplication -ObjectId {アプリのGUID} -ReplyUrls @("http://{ACSのURL}")」
    をしてあげます。

    以上、終了です。

    先ほどと同様にGet-AzureADApplicationで確認するとちゃんとhttpスキームでReplyUrlsが登録されていることがわかります。もちろんデフォルトのhttpsを残したままhttpのモノを追加してもOKです。単純に配列に値を追加すれば良いだけですので。

    結果、非SSLなアプリケーションへもSSO出来るようになりました。


    管理ポータルでも構成が出来る

    どうしてもPowerShellに抵抗がある人は手を挙げてください。
    はい、実は管理ポータルでも構成変更が出来ます。
    (こちらがTechSummit当日にご紹介した内容です)

    やり方は登録されているアプリのマニフェストを直接編集します。
    変更する内容はPowerShellの場合と同じく、ReplyUrlsの値です。





    スライドにも書いてありますが、ここを変えても元々のエンタープライズアプリケーションのSSOの設定の表示が変わるわけではありません。


    取り敢えず今回は一つ目の話を解説しました。
    2つ目以降についても順次紹介していきたいと思いますので、しばしお待ちください。