SharePoint Onlineで発生する「AADSTS90023: Invalid STS request」エラーをPythonで解消する方法

PythonでSharePoint Onlineにアクセスしようとしたときに、認証エラーが頻発してなかなか先に進めない……そんなお悩みをお持ちの方も多いのではないでしょうか。今回は「AADSTS90023: Invalid STS request」というエラーに焦点を当て、その原因や具体的な解決策、実践的なコード例などを詳しく解説します。ぜひ最後までご覧いただき、スムーズにSharePoint Onlineへアクセスできる環境を整えてください。

SharePoint OnlineへのPythonアクセスで遭遇するエラー概要

SharePoint OnlineにPythonからアクセスする場合、多くの方が「office365-rest-python-client」というライブラリを活用しています。しかし、このライブラリを使ってユーザー名とパスワードで認証を試みると、次のようなエラーが出ることがあります。

ValueError: An error occurred while retrieving token from XML response: AADSTS90023: Invalid STS request.

「AADSTS90023: Invalid STS request」とは、Azure AD(Azure Active Directory)の認証において何らかのリクエスト不備がある場合に返されるエラーです。具体的には、組織のテナント設定や認証フローの変更により従来の認証方法が使えなくなっているケースなどで頻出します。

なぜユーザー名+パスワードの認証が使えない場合があるのか

SharePoint OnlineをはじめとするMicrosoft 365サービスは、既に「モダン認証(OAuth 2.0)」が標準となっています。また、多くの組織がセキュリティ強化の一環として、MFA(多要素認証)や条件付きアクセスポリシーなどを導入し、従来の単純な「ユーザー名+パスワード」でのアクセスを制限する傾向にあります。
そのため、昔ながらのBasic認証に近い形式では、Azure ADから「正しくないリクエスト」とみなされて弾かれることが多くなっているのです。

旧認証フローの廃止

Microsoftは2022年末から2023年にかけて、Exchange Onlineなどを含む各種サービスでLegacy Authenticationを順次廃止しています。SharePoint Onlineについても同様に、今後は「ユーザー名+パスワード」単体でのアクセスが難しくなり、モダン認証に統合される流れが強まっています。

エラーの主な原因と対処法

ここでは、「AADSTS90023: Invalid STS request」が発生する原因と、その対処方法を複数の観点から整理していきます。

1. 認証方法の見直し

最も重要なポイントは、認証方法をモダン認証(OAuth 2.0)に切り替えることです。
以下は代表的な方法です。

認証方法概要
MSALライブラリを使用Microsoft公式のPython用ライブラリ。「msal」というパッケージを利用し、Azure ADからトークンを取得。
アプリ登録を行い、client_idやsecretなどを用いてOAuth 2.0認証フローを実装する。
office365-rest-python-clientによるclient_credentialsoffice365-rest-python-clientが提供する「client credentials flow」を利用。
テナントにアプリケーションを登録し、発行されたclient_idとclient_secretを使う方法。

Azure ADでの認証フローが旧来のパスワード認証ではなく、アプリケーション登録をベースとしたトークン取得に切り替わることで、「AADSTS90023: Invalid STS request」のような認証エラーを回避しやすくなります。

2. パッケージと環境設定の確認

Pythonやライブラリのバージョンが古い場合、現在のAzure ADの仕様変更に対応できない可能性があります。特に「office365-rest-python-client」は頻繁に更新されていない印象を持たれる方も多いですが、GitHubリポジトリやPyPIなどをチェックし、最新バージョンへ更新するだけでも問題が解消するケースがあります。
加えて、Python 3.11のような新しいバージョンでは依存パッケージがサポート対象外となる場合もあるため、READMEやドキュメントを再確認してみてください。

3. サイトURLやアカウント情報の誤り

SharePoint OnlineのURLが誤っている、またはユーザーのパスワードに特殊文字(&, %, #など)が含まれている場合、意図しないエンコードエラーでリクエストが失敗することがあります。
もしパスワードに記号が多用されている場合、あらかじめ別のパスワードで試すか、ソースコード上でパスワード文字列を扱う際に注意を払いましょう。文字列リテラルや環境変数を使用する場合は、以下のような取り扱いをおすすめします。

import os
from office365.sharepoint.client_context import ClientContext

username = os.environ.get('SP_USER')
password = os.environ.get('SP_PASS')  # 環境変数から安全に取得

site_url = "https://<テナント名>.sharepoint.com/sites/<サイト名>"
ctx = ClientContext(site_url).with_credentials(username, password)

# ファイル一覧を取得するなどの処理
try:
    web = ctx.web
    ctx.load(web)
    ctx.execute_query()
    print("サイトタイトル:", web.properties["Title"])
except Exception as e:
    print("エラー:", e)

上記の例では、あらかじめ端末環境変数(SP_USERSP_PASS)をセットしておき、コード内ではそれを参照する形にしています。特殊文字の扱いミスを回避しやすくなるため、エンコード不備の可能性を低減できます。

モダン認証(client_id+シークレット)を用いた具体的なアクセス方法

より確実にSharePoint Onlineへアクセスしたい場合は、Azure ADアプリを登録して「client_id」「client_secret」を用いる方法が推奨されます。ここではoffice365-rest-python-clientを利用したサンプルを示します。

Azure ADのアプリ登録

  1. Azureポータルにアクセスし、「アプリの登録」を選択。
  2. 「新規登録」をクリックして、アプリ名とリダイレクトURI(不要な場合は空でも可)を指定。
  3. 登録後に表示されるアプリケーション(クライアント)ID(client_id)をメモする。
  4. 「証明書とシークレット」から「新しいクライアントシークレット」を作成し、表示された値を安全な場所に保存する(後で二度と確認できなくなるため)。

アプリの権限設定

アプリケーションがSharePoint Onlineにアクセスするためには、「Microsoft Graph」や「SharePoint API」に対する適切な権限を設定する必要があります。例として、「Sites.Read.All」「Files.ReadWrite.All」などを付与します。
アプリ登録画面の「APIのアクセス許可」から「必要なアクセス許可を追加」し、管理者の同意が必要な場合はグローバル管理者アカウントで「管理者が同意」を行います。

Pythonコード例:office365-rest-python-clientでclient_credentialsを使用

import os
from office365.runtime.auth.client_credential import ClientCredential
from office365.sharepoint.client_context import ClientContext

# 環境変数にclient_id, client_secretを設定しておく
client_id = os.environ.get('AZURE_CLIENT_ID')
client_secret = os.environ.get('AZURE_CLIENT_SECRET')

# SharePointサイトのURL
site_url = "https://<テナント名>.sharepoint.com/sites/<サイト名>"

# 資格情報オブジェクトを作成
credentials = ClientCredential(client_id, client_secret)

# ClientContextを生成
ctx = ClientContext(site_url).with_credentials(credentials)

try:
    # SharePointのWebオブジェクトをロードしてサイト名を取得
    web = ctx.web
    ctx.load(web)
    ctx.execute_query()
    print("サイトのタイトル:", web.properties["Title"])
except Exception as e:
    print("エラーが発生しました:", e)

このようにclient_credentialsを用いれば、ユーザー名とパスワードを使わないため、MFAや条件付きアクセスの制約を回避できるケースが多いです。組織ポリシーによりアプリが弾かれないよう、適切な権限設定と管理者の承認を得ることが重要となります。

その他の認証方法(MSALライブラリの活用)

公式のMSAL(Microsoft Authentication Library)を使えば、より柔軟なトークン取得やトークンキャッシュの管理が可能です。特にユーザーごとの対話型認証を扱いたい場合や、リフレッシュトークンのライフサイクルを制御したい場合に有効です。

MSALを使った認証フロー例

import os
import msal

tenant_id = "<テナントID>"
client_id = os.environ.get("AZURE_CLIENT_ID")
client_secret = os.environ.get("AZURE_CLIENT_SECRET")

authority = f"https://login.microsoftonline.com/{tenant_id}"
scope = ["https://graph.microsoft.com/.default"]  # または必要なAPIのスコープ

app = msal.ConfidentialClientApplication(
    client_id,
    authority=authority,
    client_credential=client_secret
)

# トークンを取得
result = app.acquire_token_for_client(scopes=scope)

if "access_token" in result:
    access_token = result["access_token"]
    print("トークン取得成功:", access_token)
    # 取得したトークンを用いて、Graph APIやSharePoint APIへのアクセスが可能
else:
    print("トークン取得失敗:", result.get("error_description"))

この方法を用いると、Access Tokenの取得がダイレクトに行えるため、独自にHTTPヘッダーにトークンを設定し、Requestsやその他のHTTPクライアントでSharePoint REST APIにアクセスするといった実装も可能になります。

追加で意識すべきポイント

条件付きアクセスとMFA

組織やテナントの設定によっては、条件付きアクセスポリシーで特定のIPアドレスやデバイスタイプのみを許可している場合があります。また、MFAが必須となっている場合、ユーザー名+パスワードだけではログインできません。
このようなケースでは、アプリ登録によるclient_credentialsを使うか、あるいは対話型認証を通す仕組みを設ける必要があります。後者の場合はブラウザなどを介した認証が必要で、スクリプトによる自動化が難しくなることがありますのでご注意ください。

専門フォーラムやコミュニティの活用

もし上記の手順を試しても問題が解決しない場合は、Microsoft Q&AのSharePoint Developmentタグや、Stack OverflowのPython・SharePoint関連トピックで質問すると、同様の問題を解決した事例を教えてもらえる可能性が高いです。
また、Python.orgコミュニティやGitHubのissueページでは、ライブラリのバージョンごとの既知の不具合やワークアラウンドを詳しく解説している場合があります。ログの詳細や使用しているコードを共有することで、より具体的なアドバイスを受けやすくなるでしょう。

ログ取得とデバッグ

原因が不明な認証エラーが出た場合には、ログを取得して詳細を分析することが大切です。Pythonでは標準のloggingモジュールや、office365-rest-python-clientのデバッグ機能を活用することで、トークン要求時のリクエストやレスポンスを可視化できます。
エラー発生時にログを追跡しておくことで、「実はテナントIDが間違っていた」「権限が不足していた」などの問題点をいち早く特定できる場合が多いです。

まとめ

SharePoint OnlineへのPythonアクセスにおいて「AADSTS90023: Invalid STS request」というエラーが発生する場合、まずは認証フローを見直し、モダン認証(OAuth 2.0)に移行するのが最も確実な解決策です。ユーザー名とパスワードのみのアクセスが難しくなっている昨今のセキュリティ事情も踏まえ、アプリケーションをAzure ADに登録してクライアントIDとシークレットを用いた認証を導入しましょう。
また、環境設定やバージョン、URL、そしてパスワードの取り扱いなど細かな部分にも気を配ることが大切です。組織のセキュリティポリシーや条件付きアクセスの要件によっては、さらに追加の設定や管理者の承認が必要になるケースもありますが、手順に従って準備すれば安定してSharePoint Onlineにアクセスできるようになります。ぜひ本記事を参考に、実践してみてください。

コメント

コメントする