Azure AD Application Proxyを経由してAzure ADをIdpとしたSAML認証を行う

SAML認証をサポートしているアプリケーションをAWS等のIaaS上に構築して、IP制限を掛けてアクセス制限しており、SAML認証とAzure AD Application Proxyを同時に利用したいケースがあったので検証しました。

MicrosoftのTech Communityの記事で、SAMLベースのアプケーションをAzure AD Application Proxyがサポートしたことは記載があり、設定方法はMicrosoftのApplication Proxyのドキュメントに記載されていましたが、これの通りに設定しても、今回はうまくいきませんでした。

上記の記事には、元々のReply URLが https://contosotravel.com/acs で、対応するApplication ProxyのExternal URLが https://contosotravel-f128.msappproxy.net の場合、Reply URLを、https://contosotravel-f128.msappproxy.net/acs に設定する必要があると記載されています。

ですが、今回検証した環境では、下記の3つのReply URLを設定する必要がありました。

https://contosotravel-f128.msappproxy.net/acs [default]
https://contosotravel-f128.msappproxy.net/
https://contosotravel.com/acs

上記3つを指定する必要があると記載されたドキュメントは見つけることができず、前述したMicrosoftのApplication Proxyのドキュメントには、Application Proxyを利用する前にReply URLに設定していた internal URLは削除することができると書いてあります。しかし、Application Proxy経由でSAML認証を行った際に表示されるエラーメッセージに沿って設定を修正していった結果、上記3つのReply URLの設定が必要という結果なりました。

エラーメッセージに沿って設定を修正したら解決できたので、1日で解決できた問題でしたが、自分ではこのことが記載されているドキュメントが見つけられなかったので、メモ代わりにここに記載します。

今回はオンプレミス環境ではないため、IP制限をかけているURL(internal URL)もインターネット上にて名前解決はできる状態です。Application Proxy利用時に想定されている通常のケースは、インターネット上ではURLの名前解決ができないアプリケーションに対してExternal URLを発行してアクセスする形と理解しています。このような想定されているケースとの環境的な差異が、Microsoft のApplication Proxyのドキュメントの通りに設定してもうまく動かなかった原因の可能性があるのかもと思っていますが、根拠はなく、関係しているとしても正直どう関係しているのかは見当もついていません。

もしMicrosoftから出されているドキュメントなどで、上記設定の根拠になりそうなものをご存じの方がいらっしゃいましたら、教えていただけると大変ありがたいです。

PowerAutomateを使ってGmailの添付ファイルをGoogleSharedDriveにファイルをアップロードする

はじめに

特定の条件にあったメールに添付されているファイルをGoogleSharedDriveにアップしたかったので、試してみました。PowerAutomateで用意されているGoogleDriveのコネクタは個人ドライブへのファイル操作は行えますが、SharedDriveに対する操作はできないという制限があるので、SharedDriveを操作するためのカスタムコネクタを作って対応しました。

GoogleDriveガイドのファイルデータをアップロードする を見たら、マルチパートアップロードでRequest bodyを作るのが手間がかかりそうと感じました。特に境界文字列を使って分割したパーツを識別したりなどが手間がかかりそうと感じました。そのため、既存のGoogleDriveコネクタを使って個人ドライブにファイルをアップロードし、カスタムコネクタで個人ドライブからSharedDriveに移動するというやり方にしました。個人的には既存で使えるものは使って楽をしたいと考えているからです。

作業手順

必要な作業は下記です。手順内で利用するGoogleアカウントは、GoogleWorkspaceのユーザーを想定しています。

手順1. Google Cloud PlatformでOAuthクライアントIDを作成する
手順2. 手順1.で作成したOAuthクライアントIDとクライアントシークレットを保存する
手順3. SharedDriveへファイルを移動するカスタムコネクタを作成する
手順4. 手順3.で作成したカスタムコネクタを利用したフローを作成する
手順5. 手順3.で作成したカスタムコネクタで利用するコネクションを作成する

手順1. Google Cloud PlatformでOAuthクライアントIDを作成する

OAuthクライアントIDを作成し、クライアントIDとクライアントシークレットを入手します。

PowerBuilder Japan Portalのこちらのページにも画像つきで方法が紹介されています。

1. Google Cloud Platform に新規プロジェクトを作成し、Google Drive APIを有効化する

Google Cloud Platformにアクセスし、Googleアカウントでログインします。その後、Google Drive APIを利用するための新規プロジェクトを作成します。

作成したプロジェクトの”APIs & Services”メニューから”library”を選択し、GoogleWorkspaceのカテゴリから”Google Drive API”を選択します。”ENABLED”のボタンをクリックし、Google Drive APIを有効化します。

2. OAuthクライアントIDを作成する

作成したプロジェクトの”APIs & Services”メニューから”Credentials”を選択し、”+CREATE CREDENTIALS”から”OAuth client ID”を選択し、OAuthクライアントIDを作成します。OAuth consent screenにてUser Typeの選択を求められた場合は、”Internal”を選択します。(自分自身または組織内のユーザーのみが利用することを想定しています。)

OAuthクライアントIDの入力項目を、下記の表に沿って入力します。

パラメタ名パラメタ値
Application typeWeb application
Name[お好きな名前]
Authorized JavaScript origins[未設定]
Authorized redirect URIshttps://global.consent.azure-apim.net/redirect
(手順3の2.Security内の画像に記載されているRedirect URLです)

手順2. 手順1.で作成したOAuthクライアントIDとクライアントシークレットを保存する

手順1で作成した新規プロジェクトとの”APIs & Service”メニューから”Credentials”を選択し、手順1で作成したOAuthクライアントの”Action”のダウンロードアイコンをクリックし、OAuthクライアント情報をダウンロードします。

手順3. SharedDriveへファイルを移動するカスタムコネクタを作成する

PowerAutomateの”Data > Custom connectors”メニューから”+ New custom connector > Create from Blank”を選び、カスタムコネクタを作成します。1.Gneral から 4. Code (Preview) まで下記のように入力します。

1. General

下記の表に沿って入力します。下記表にない項目は自由に入力します。

パラメタ名パラメタ値
Schemahttps
Hostwww.googleapi.com
Base URL/

2. Security

下記の表に沿って入力します。

パラメタ名パラメタ値
Choose what authentication is implemented by your APIOAuth 2.0
Identity ProviderGoogle
Client ID[手順2で保存OAuthクライアントID]
Client secret[手順2で保存したクライアントシークレット]
Scopehttps://www.googleapis.com/auth/drive

3. Definition

”+ New action”メニューから新しいアクションを追加し、”+ Import from sample”を選択し、Requestを下記の表に沿って入力します。”{}”で囲んだ部分は変数としてカスタムコネクタに認識されます。

下記表に入力しているパラメタは、GoogleDriveのfile updateのAPIリファレンスを参考にしています。

パラメタ名パラメタ値
VerbPATCH
URLhttps://www.googleapis.com/drive/v3/files/{fileID}?addParents={addParents}&removeParents={removeParents}&supportsAllDrives={supportsAllDrives}
Body{}

Queryパラメタの設定を下記の表に沿って入力します。下記表にない項目は自由に入力ください。

パラメタ名 / パラメタ値AddParentsremoveParentssupportsAllDrives
is required?yesremoveParentsno
Typestringstringboolean

4. Code (Preview)

Code Detailsの部分のトグルボタンをクリックし、”Code Disabled”にします。”Code Enable”になっているとFlowを実行したときに、ここに記載しているテストが実行されます。

手順4. 手順3.で作成したカスタムコネクタを利用したFlowを作成する

“My flows”メニューから”+New flow”を選択し、”Automated clod flow”を選択します。新しいFlowのトリガーは、Gmailの”When a new email arrives”を選択して、Flowを作成します。

下記画像を参考にSharedDriveに保存したいファイルが添付されたメールを抽出できるよう”When a new email arrives”のフィルター条件を設定してください。

次に添付ファイルを個人ドライブに保存するために、既存のGoogleDriveコネクタのCreate fileアクションを追加して、各パラメタを下記表に沿って入力します。

パラメタ名パラメタ値
Folder path[個人Drive内のフォルダパス]
(フォルダアイコンをクリックしてGUIで個人Driveの中のフォルダを選択できます。
認証を求めらたらGoogleアカウントで認証してください。認証するとGoogleDriveのコネクションが作成されます。)
File name[GmailのAttchments Name]
 File content[GmailのAttachments Content]

次に、個人Driveに保存したファイルをSharedDriveに移動するために、手順3で作成したカスタムコネクタのmovefileアクションを追加して、各パラメタを下記表に沿って入力します。

パラメタ名パラメタ値
fileID[GoogleDriveのid]
addParents[移動先SharedDriveのフォルダID]
(フォルダIDの調べ方はメシラボさんの記事がわかりやすかったです)
removeParents[移動元個人DriveのフォルダID]
supportsAllDrivesYes
body[無記入]

ここまで入力したら作成したFlowを保存してください。

手順5. 手順3.で作成したカスタムコネクタで利用するコネクションを作成する

“Data”メニューから”Custom connectors”を選択し、手順3.で作成したカスタムコネクタの横にある”+”を選択します。Googleアカウントでの認証を求めらるので、Googleアカウントで認証してください。


これで準備は完了です。Gmailにファイルが添付されたメールを送り、SharedDriveにファイルが保存されるかをご確認ください。

説明がわかりづらい部分もあるかと思いますが、お役にたちましたらうれしいです。

音声入力に助けられた

先週末、家族で川遊びをした時に転んでしまって、左手の中指を少し折ってしまった。幸いけがは大したことなかったものの左手の親指を残す四本は包帯でぐるぐるに巻かれているため、タイピングができない。左手でタイピングに使えるのは親指と中指のみ、いつもより作業効率が落ちるのは目に見えている。

すこしでも効率を落とさないために何かできることはないかと考えて、思いついたのが音声入力だった。Windowsにはたしか標準でついたことを思い出し、早速試してみた。

これが思ったよりよかった。 ある程度長く話すと変換の精度もなかなかである。アルファベットを打ち込むことには向かないので、スクリプトや設定ファイルを書くことはできないけれど、チャットに返信したり、メールを書いたり、ドキュメントを書くのには充分使えた。ドキュメント内に出てくるアルファベットはカタカナで表記されてしまうため、後で自分で書き直す必要があるが、全部を今の自分が書くよりは全然早い。

また、考えていることを外に出すときは、独特の気持ちよさがあると感じた。タイピングする時に、対して何か妨げられて無い感覚がある。一回できれいな文章を書こうとすると、もちろんタイピングの方が良いのだけれど、考えていることをただつらつらとメモるだけであれば音声入力の方が、一気に書きやすい気がした。

当初は怪我している間の代替手段として始めた音声入力だったけれど、自分の考えをまとめたり、かき出したりという用途だったら、今後も使えそうな気がする。資料を眺めながら気に入ったところメモしたり、資料の感想をただダラダラと喋って行くのにもむいていそうと思っている。

あとボソボソとしゃべると認識率が下がるので、聞き取りやすくはっきり喋ると言う必要はある。大きな声で話す必要はないけれど、きちんと口を開けて動かしてしゃべるというイメージ。これはオンラインミーティングで相手が聞き取りやすく話すということの訓練にも使えるかもしれない。

在宅勤務で働いている方ならヘッドセットやマイクも揃っているので、すぐにでも始められると思う。考えをまとめるとき、なんとなく手が疲れたっていう時、音声入力を試してみると、いいかもしれない。

Microsoftのプライバシー関係のドキュメント

Microsoftサービス(AzureとかMicrosoft365)とかのドキュメントいっぱいあるなーと思いながら、いつも読むのが途中になって、次に読み始めた時に、何読んでたのか覚えていないとなっていた。

今回は、あとで読みかえすため、どんな文書読んでたかを残しておきたので、ブログに書きます。単なるリンク集ですが、自分にとっては、きっと後で見返す、大事なものになると思うので。

Privacy Statement

terms of use

Microsoftサービス規約

プライバシー

Microsoftはお客様のデータをクラウドの中でどあつかうか(ホワイトペーパー)

お客様のデータに誰がどのような条件でアクセスできるか (サブプロセッサーのリストもあり)

Microsoftによるオンラインサービスのデータ分類方法

AzureADのデータ保管場所

Microsoftでのデータ管理

お客様のデータの保管場所

Microsoft 365のデータ保管場所

Microsoft Azureの法的情報

サービスレベルアグリーメント

Azureのセキュリティのドキュメント

Microsoftコンプライアンスのサービス

WindowsUpdateが上手くいないときにためすこと

仕事でWindowsUpdateでのWindows10大型アップデートがうまくできない端末があって、対応しているんんですが、下記リンクで、WidnowsUpdateのユーザデータをクリアするというのは、うまくいかない場合に必ずやってみてください。

あと、トラブルシューティングツールで、WindowsUpdateの問題の解決と、ディスクのプロパティから選べるシステムファイルを対象にしたディスククリーンを実行すると、クライアント側のデータは全て消えます。

まずはこれから試してみてください。

 

https://blogs.technet.microsoft.com/jpwsus/2014/12/02/windows-update-3/

CPUの世代での違い

久々にブログを書こうと思い立ったんですが、何も準備していなかったので、最近驚いたことを書いておきます。最近、会社で新しいPCが支給されたり、自分でもPCを買ったりして、複数のPCを触る機会がありました。ここで体験したのが、CPU世代での性能差です。

使ったPCは、下記の3つ
・VAIO S13(CPUはインテル6世代のCOREi7)
・DELL XPS13(CPUはインテル7世代のCOREi7)
・富士通LIFEBOOK UH(CPUはインテル7世代のCOREi5)

VAIOはまだ2年も使っていないモデルで、会社でメインで利用しています。通常の利用に不満はないです。DELL XPSは家用に買ったPCで、VAIOよりも性能がいいのはわかった上で触っているのですが、びっくりしたのは富士通LIFEBOOK。CPUはi5なのに、データ量と数式が多く入ったEXCELファイルを開いたときの速度が、富士通LIFEBOOKの方が、VAIOよりも速かったんです。時間がかかるEXCELの式の再計算に差があったように見えたので、CPUの差だと考えられます。

世代が1世代違ってもi7が優位だと漠然と思っていたんですが、アーキテクチャの進化は想像以上に大きかったです。値段は富士通LIFEBOOKよりDELL XPSの方が安いので、DELL XPSの方がお買い得感があります。DELLの直販サイトでは頻繁に割引もやっているので、週に一回くらいチェックすると、よりお得なキャンペーンで購入することがあります。今(8/12)にやっているキャンペーンは18000円引き+5%オフなので、だいぶお得です。僕が買ったときより安いですね。14万くらいでi7モデルが買えてしまいます。

軽さをもとめる人は、富士通LIFEBOOKです。1kgを切っています。macbookより軽いので持ち歩いでも苦になりません。XPSより高いし、CPUのランクも落ちますが、使い比べなければわからないレベルでしょうし、重さはXPSの2/3程度です。(LIFEBOOKは約800g、XPSは約1200g)

これからは、PCを購入する際に1世代とはいえ、CPUの世代はCPUのランク以上に意識する必要があるデータとして考えていきます。次は、家のメインPCのiMacの買い替えですね。XPS用に4Kの外付けディスプレイも購入したので、次はMacBook Proの15インチにして、机の上をすっきりさせたいと考えています。iMacもスペックも価格も値上がりしているので、迷うところです。iMacはデスクトップ用のCPUを積んでいるのでクアッドコアというのが魅力です。購入資金はまだないし、iMacもMacBook Airも現役で働いてくれているので、購入はまだ先になりそう。今月に第二子も生まれて、また色々買うものも出てきますしね。

WindowsPCを購入する際の参考になればと思います。国産PCだと、今の富士通LIFEBOOKはかなりいいと想います。VAIOが第7世代のCPUを積んできたら、VAIOもいいですね。デザインと使い勝手でいうと、富士通LIFEBOOK、VAIO、DELL XPSのどれかではないかと思います。

is_subclass_ofを使う場面

is_subclass_ofというメソッドを見つけました。機能は、指定したクラスを継承しているかを判定してくれるというものです。

instanceofやis_aメソッドを使った判定と同じイメージです。違いはinstanceofやis_aがオブェジェクトだけを判定できるのに対して、is_subclass_ofはクラス名について判定することができます。

クラスからオブジェクトを生成する前に判定が可能ということです。

複数のプログラマが利用する共通部を作成するような場合に使えそうです。今回は、あるディレクトリ配下のクラスファイルを全て読み込んで、特定のクラスを継承しているクラスのみ生成するという処理に利用しました。

誤ったファイルを置かれても、不具合が出ないための対応ですが、ちゃんと作れとか、ルールが明記してあるドキュメントを整備しろとかあるとは思いますが、これはこれでいい対策かなと思います。

advanced custom fieldsがプレビューに対応していた

以前、advanced custom fieldsプラグインでプレビューもやりたいという記事を書きましたが、最新版ではプレビューにも対応していました。

プラグインをアップデートしたら、以前の記事に書いたプレビュー対応の部分でエラーがでたため、一旦外したところ、外した後もプレビューできていました。これからは、プラグインを有効化するだけで、プレビューにも対応可能ですね。

手間が減るって嬉しいことです。中身がどう変わったのかも、見てみようと思います。

Zend_Framework1のDbMetaキャッシュ設定をapplication.iniで行う

ZendFramework1は、DBアクセスする際に、DbMeta情報を取得します。
MySQLだと、describeで取得できるテーブルの構造です。
この情報は、あまり変わらないのでキャッシュすることで、性能アップが実現できます。

以前、“ZendでDbのMeta情報をキャッシュする”という記事で書かせて頂いたように、Bootstrapの中で定義していました。

    protected function _initDbCache()
    {
        $frontendOptions = array('automatic_serialization' => true);
        $backendOptions = array('cache_dir' => APPLICATION_PATH . '/../cache/db');
        $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
        Pb_Db_Table_Abstract::setDefaultMetadataCache($cache);
    }

これ、application.iniに設定を書くことで、全く同じことが実現できました。
問題無く動いていたし、Bootstrap自体が修正が入ることが少なかったので、気づきませんでした。
以下のように、記述することで、ソースコードを書く必要がなくなります。
書かなくていいものは、書かない方がいいですよね。

; dbメタキャッシュ設定
resources.cachemanager.db.frontend.name  = "Core"
resources.cachemanager.db.frontend.customFrontendNaming = false;
resources.cachemanager.db.frontend.options.lifetime = 7200
resources.cachemanager.db.frontend.options.automatic_serialization = true
resources.cachemanager.db.backend.name = "File"
resources.cachemanager.db.backend.customBackendNaming = false;
resources.cachemanager.db.backend.options.cache_dir = APPLICATION_PATH . '/../cache/db'
resources.cachemanager.db.frontendBackendAutoload = false

Zend_Framework2では、どんな設定方法になるんだろう。
まだ触っていないので、書くことはできませんが、わかったら書きたいと思います。

php5.4からはerror_reportingのE_ALLにE_RISTRICTが含まれる

error_reportingは、php.iniの中に書かれている設定で、どのレベルのエラーを出力するかの設定です。このE_STRICTのエラーは、php5でphp4の書式で記述されているプログラムを実行すると、大量に出ます。static定義されていないメソッドを、クラス名::メソッド名で呼んだりしたときに出るのです。

E_ALLは、全部のエラーを出力してねっていう設定です。
これまでは、”E_ALL & ~E_NOTICE”とかでNOTICEメッセージを抑止している方もいたと思います。このE_ALLのなかに、E_STRICTで表示されるメッセージは含まれていなかったのです。今まで。それが、php5.4からは、E_ALLに含まれることになりました。

php5.4に上げた途端エラーメッセージが大量に!って場面に遭遇するのです。
PAER使っている方は、必ず遭遇するのではないでしょうか。php4でも動作するように作られているので。

E_STRICTのエラーを表示しないためには、以下のように記述します。

error_reporting = E_ALL & ~E_STRICT

php.iniのコメントでも親切に例がのってました。

; Common Values:
;   E_ALL (Show all errors, warnings and notices including coding standards.)
;   E_ALL & ~E_NOTICE  (Show all errors, except for notices)
;   E_ALL & ~E_NOTICE & ~E_STRICT  (Show all errors, except for notices and coding standards warnings.)
;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED  <= こことか
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT           <= こことか
; http://php.net/error-reporting
; error_reporting = E_ALL | E_STRICT
error_reporting = E_ALL & ~E_STRICT & ~E_DEPRECATED

php4から持ってきたプログラムがうまく動かないと聞かれて調べてたんですが、勉強になりました。
以下のサイトを参考にさせて頂き、大変ありがたかったです。

http://developer.cybozu.co.jp/tech/?p=982
http://vivit-jc.hatenablog.com/entry/2013/02/12/210950
http://blog.gufii.net/weblog/archives/19