【azure】シングルページアプリケーションクライアントタイプ用に発行されたトークンは、クロスオリジン経由でのみ引き換え可能です

Azure auth2エラーコード説明表

https://learn.microsoft.com/en-us/azure/active-directory/develop/reference-error-codes

エラーを報告する

AADSTS9002327: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests

物語の背景

新しいトークンと更新トークンを取得するには、azure 経由で office365 (AAD) を呼び出す必要があります刷新令牌ブラウザ側のコンテナではこれは問題ありません (スパ アプリケーションであり、PKCE 認証フローを使用するため) が、マイクロ フロントエンド mricro-app によってコンテナのベースとして導入されたサブアプリケーションでは問題が発生します。電子の場合、オリジンをリクエスト ヘッダーに正常に追加できません。

分析する

2 つの推測があります
: 1. Electron のリクエスト インターセプターがリクエスト ヘッダーを書き換え、サブアプリケーションのオリジンが書き込まれるのを防ぎます。
2. ブラウザのセキュリティ機構により、クロスオリジンの場合、オリジンは表示されません。

解決

特定のリクエスト ヘッダー タグを指定し、このタイプのリクエストをインターセプトし、渡された値として指定される属性を手動で追加することで、これを直接electron的请求拦截器処理しました。サブアプリコード:vv-originelectron请求拦截器originvv-origin

const url = `https://login.microsoftonline.com/${
      
      off_tenant}/oauth2/v2.0/token`;
  const params = {
    
    
    client_id: off_clientId,
    scope: off_scopes.join(' '),
    refresh_token: refreshToken,
    grant_type: 'refresh_token',
  };

  axios
    .post(url, params, {
    
    
      headers: {
    
    
        'Content-Type': 'application/x-www-form-urlencoded',
        'vv-origin': 'http://localhost',  // 自定义了一个vv-origin头,方便electron下的微前端基座应用拦截请求头,如果写成origin可能会被重写掉导致拦截不到
      },
    })
    .then((res) => {
    
    
      console.log('success===>', res);
      if (res && res.data) {
    
    
        const data = res.data;
        // 获得刷新后的token和refreshToken
        const opts = {
    
    
          serviceId,
          refreshToken: data.refresh_token,
          accessToken: data.access_token,
          expiresIn: data.expires_in,
          email,
        };
        console.log('使用刷新令牌从office获取新的访问令牌', data, opts);
        updateBindEmailInfo(opts);
      }
    });

デスクトップ側の Electron アプリケーションがリクエストをインターセプトするコードは次のとおりです。

    interceptorsRequest() {
    
    
        session.defaultSession.webRequest.onBeforeSendHeaders(
            async (detail: Electron.OnBeforeSendHeadersListenerDetails, callback) => {
    
    
                this.requestMap[detail.id] = pick(detail, [
                    'id',
                    'url',
                    'method',
                    'resourceType',
                    'timestamp',
                    'requestHeaders'
                ]);
                if (detail.requestHeaders['vv-origin']) {
    
    
				    callback({
    
    
				        requestHeaders: {
    
    
				            ...detail.requestHeaders,
				            origin: detail.requestHeaders['vv-origin']
				        }
				    });
				}
 				callback({
    
     responseHeaders: headers });
        });
    }

参照元: https://stackoverflow.com/questions/61231144/getting-access-tokens-from-postman-tokens-issued-for-the-single-page-applicati

おすすめ

転載: blog.csdn.net/hzxOnlineOk/article/details/131393694
おすすめ