CSOMでのSharePoint Onlineへの先進認証アクセス方法
本ブログをご覧いただきましてありがとうございます。
マイクロソフトクラウドグループ2年目のshibuya.hです。
PowerShellのSharePointクライアント サイド モデル(以下、CSOM)をトークンを取得してSharePoint Online(以下、SharePoint)に接続する方法を説明します。
私自身もトークンベースのSharePoint接続は、かなり苦労した経験があり、
その経験を他の人に活かしてもらえればという思いで本記事を書いています。
目次
1.導入
久しぶりにCSOMでSharePoint サイトにアクセスを試みたところ、、、
あれ?? 処理が失敗してる。。。
Error: "0" 個の引数を指定して "ExecuteQuery" を呼び出し中に例外が発生しました: "Identity Client Runtime Library (IDCRL) did not get a response from the Login server."
どうやら、SharePointへの接続に先進認証が必須へと変更されていました。
Exchange Onlineベーシック認証の廃止
SharePoint Online認証の代替手段
Microsoft GraphやExchange Onlineのモジュールだと認証画面がでてきたのに、CSOMは出てこない!!
■認証画面
ということで、CSOMではSharePointとの通信に際して「トークン」と呼ばれる認証情報を付与する必要があります。
今回はトークンの取得のために、Entra IDの「アプリケーション」を使用します。
アプリケーションは各テナントのサービスにアクセスする際に必要な権限を設定する機能です。
トークンとは、アプリケーション登録時に作成される「サービスプリンシパル」の情報を文字列にしたものです。
また、サービスプリンシパルとはアプリケーションに付与したアクセス権限やロールが含まれた認証情報です。
簡単に言えばアプリケーションとはユーザーで、トークンとはそのユーザーにログインしている状態であることを表す情報という認識です。
ユーザーにログインするためには、パスワードが必要ですよね。ということでアプリケーションのパスワードには、「証明書」を使用します。
少しややこしくなったので情報を整理すると、
『サービスプリンシパル』 + 『証明書』 ⇒ 『トークン』 となります。
2.実践(具体的な内容)
2.1.前提条件
・実行ユーザーにEntra IDの管理者権限を付与されていること
2.2.事前準備
下記のモジュールのインストール
・SharePoint Online Client Components SDK(CSOM)
・Microsoft.Identity.Client ※最新バージョンを推奨
証明書の用意
・~.pfx
・~.cer
今回は自己証明書を使用します。
自己証明書は以下に記載したPowerShellのコマンドから発行しました。
# 証明書出力先 $pfxFilePath = "c:\work" # Cドライブ直下のworkフォルダを指定 # 証明書作成に必要な情報 $cert = New-SelfSignedCertificate ` -Subject "CN=PFX-cert" ` -NotAfter (Get-Date).AddYears(1) ` -KeyExportPolicy Exportable ` -KeySpec Signature ` -KeyLength 2048 ` -HashAlgorithm sha256 ` -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" ` -CertStoreLocation "cert:\LocalMachine\My" # パスワード入力 $password = Read-Host -Prompt ".pfxファイルのパスワードを入力してください" -AsSecureString # PFXファイルのエクスポート $cert | Export-PfxCertificate -FilePath $pfxFilePath\PFX-cert.pfx -Password $password # CERファイルのエクスポート $cert | Export-Certificate -FilePath $pfxFilePath\PFX-cert.cer Write-Host "証明書ファイルを作成しました。" Write-Host "$pfxFilePath\PFX-cert.pfx" -ForegroundColor Green Write-Host "$pfxFilePath\PFX-cert.cer" -ForegroundColor Green
2.3.Entra IDでの設定(アプリケーション登録)
2.3.1.アプリの登録
Microsoft Entra 管理センターにログインして、SharePointへのアクセスに使用するサービスプリンシパルの設定を行います。
・『アプリの登録』タブから新規登録を押下
・アプリケーションの表示名を入力し、登録
アプリを使用できるユーザーは自分のテナントのみに制限したいので、「この組織ディレクトリに含まれるアカウント」を選択してます。
CSOMでトークンを使用する場合は、リダイレクトURIも未設定で大丈夫です。
2.3.2.証明書のアップロード
登録したアプリケーションに、認証を行うための証明書をアップロードします。
・登録したアプリケーションを開き、『証明書とシークレット』タブを選択
・『証明書のアップロード』を押下して、事前準備で作成した証明書ファイル(.cer)をアップロード
2.3.3.アクセス許可の設定
作成したアプリケーションに権限の設定を行います。
・『APIのアクセス許可』タブから『アクセス許可の追加』を押下
・SharePointの『アプリケーションの許可』から『Sites.Read.All』を追加
※今回はサイトの名前を取得するだけなので、サイトの読み込み権限『Sites.Read.All』を付与しています。
・「~に管理者の同意を与えます」を押下して、アクセス許可を適用
2.4.実行スクリプト開発
PowerShellでトークンを取得して、SharePointの認証を通すスクリプトを作成しました。
# モジュールのインポート Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll" Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll" Add-Type -Path "C:\Program Files\WindowsPowerShell\Modules\Microsoft.Identity.Client\4.8.1\Microsoft.Identity.Client.dll" # バージョンに注意 # 変数を設定 $SharePointSite = '' # 接続先SharePoint OnlineのルートサイトURL $siteUrl = '' # 接続先SharePoint Onlineのサイト内部アドレス $certificatePath = '' # .pfx証明書の絶対パスを入力 $certificatePassword = '' # .pfx証明書のパスワード(作成時に設定) $ClientId = '' # クライアントID(アプリケーションID) $TenantId = '' # テナントID(ディレクトリID) try { # SharePoint Online 接続情報作成 $certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certificatePath, $certificatePassword) $authorityUrl = "https://login.microsoftonline.com/$TenantId" # 接続情報作成 $confidentialClientApp = [Microsoft.Identity.Client.ConfidentialClientApplicationBuilder]::Create("$ClientId") $confidentialClientApp = $confidentialClientApp.WithCertificate($certificate) $confidentialClientApp = $confidentialClientApp.WithAuthority($authorityUrl) $confidentialClientApp = $confidentialClientApp.Build() # アクセストークンを取得 [string[]]$scopes = "$SharePointSite/.default" $authResult = $confidentialClientApp.AcquireTokenForClient($scopes).ExecuteAsync().Result $token = $authResult.AccessToken # HTTPリクエストにアクセストークンを追加 $context = New-Object Microsoft.SharePoint.Client.ClientContext("$SharePointSite/$siteUrl") $context.add_ExecutingWebRequest({ param($sender, $e) $e.WebRequestExecutor.WebRequest.Headers["Authorization"] = "Bearer $token" }) $context.Load($context.Web) $context.ExecuteQuery() } catch { Write-Error "SharePoint Onlineに接続できませんでした。" exit } # サイト名を取得して表示 $siteTitle = $context.Web.Title Write-Host "SharePoint Onlineへの接続に成功しました。" -ForegroundColor Green Write-Host "接続先サイトの名前: $siteTitle" -ForegroundColor Green
以下を参考にスクリプトを編集してください。
2.4.1.モジュールのファイルパス
参照しているインポートモジュールのファイルパスが正しいことを確認してください。
例:「Microsoft.Identity.Client.dll」
“C:\Program Files\WindowsPowerShell\Modules\Microsoft.Identity.Client\4.8.1\Microsoft.Identity.Client.dll”
2.4.2.SharePointのURL
$SharePointSite = 'https://isorootblog.sharepoint.com' # 接続先SharePoint OnlineのルートサイトURL $siteUrl = 'sites/isorootblog' # 接続先SharePoint Onlineのサイト内部アドレス
ルートサイトURLとサイト内部アドレスは以下の画像を参考にしてください。
■ルートサイトURL
■サイト内部アドレス
2.4.3.証明書のファイルパスとパスワード
$certificatePath = 'c:\work\PFX-cert.pfx' # .pfx証明書の絶対パスを入力 $certificatePassword = '*****' # .pfx証明書のパスワード(作成時に設定)
証明書(.pfx)が配置されているフォルダの絶対パスと証明書発行時に設定したパスワードを設定してください。
2.4.4.アプリケーションIDとテナントID
$ClientId = '' # クライアントID(アプリケーションID) $TenantId = '' # テナントID(ディレクトリID)
アプリケーションIDとテナントIDは作成したアプリケーションから確認することが出来ます。
■アプリケーションID
■テナントID
2.5.スクリプト実行
修正したスクリプトをPowerShellで実行します。
作成したアプリケーションからトークンを取得し、CSOMでSharePointサイトのサイト名を取得することが出来ました!!
3.まとめ
今回はアプリケーション登録で作成したアプリケーションからトークンを取得して、CSOMモジュールでの認証に使用する方法について説明しました。
アプリケーション登録を行うことで、さまざまな自動実行処理をユーザー認証の手間なく実行し、業務効率化や夜間バッチ処理などのシナリオで使用できます。
是非、活用してみてください。
4.終わりに
OAuth 2.0が一般化しつつある今、Microsoftが推奨する認証方法も大きく変わりました。
アプリケーション登録は一度理解してしまえば幅広く応用が利く重要なテーマです。
これからも継続して勉強し、知見を深めていきます。
それでは、また別の機会にお会いしましょう。