是否有方法在后端验证Microsoft Graph API的Azure访问令牌?

j0pj023g  于 2023-04-07  发布在  其他
关注(0)|答案(1)|浏览(111)

我为我的前端配置了一个Azure应用程序。从中,我从Azure获取Microsoft Graph API的访问令牌。这是我的前端授权配置。

import { PublicClientApplication } from '@azure/msal-browser';

const msalConfig = {
  auth: {
    clientId: '#####',
    authority:
      'https://login.microsoftonline.com/#####', 
    redirectUri: '#####'
  },

  cache: {
    cacheLocation: 'localStorage', 
    storeAuthStateInCookie: true 
  }
};

export const loginRequest = {
  scopes: ['User.Read', 'User.ReadBasic.All']
};

const msalInstance = new PublicClientApplication(msalConfig);

这就是我在前端获取访问令牌的方式。

import { msalInstance, loginRequest } from './auth.config';
const accounts = msalInstance.getAllAccounts();
if (accounts.length <= 0) return;
try {
   const response = await msalInstance.acquireTokenSilent({
     ...loginRequest,
      account: accounts[0]
   });
   // response.accesstoken is obtained
} catch (error) {
   console.error(error);
}

当我调用后端API时,我将此令牌作为bearer令牌在请求中发送给后端,我需要在后端验证它。这就是我卡住的地方。我尝试过,但我无法在后端验证此令牌。
由于这个访问令牌是一个jwt令牌,我尝试用以下方式验证它。

import jwt, { JwtPayload } from 'jsonwebtoken';
import { IPublicKey } from './interfaces';
import jwkToPem from 'jwk-to-pem';

async function getKeysUri(): Promise<string> {
    // Get jwks_uri from following meta data url.
    // https://login.microsoftonline.com/{tenant_id}/.well-known/openid-configuration?appid=###
}

async function getKeyForKid(kid: string, jwksUri: string): Promise<IPublicKey> {
    // Get keys from jwksUri
    return keys.find((obj: IPublicKey) => obj.kid === kid);
}

export async function verifyAccessToken(accessToken: string): Promise<JwtPayload> {
    try {
        const decoded = jwt.decode(accessToken, { complete: true });
        const kid = decoded.header.kid;
        const jwksUri = await getKeysUri();
        const key = await getKeyForKid(kid, jwksUri);
        const pem = jwkToPem(key);
        const payload = jwt.verify(accessToken, pem) as JwtPayload;
        return payload;
    } catch (err) {
        console.error(err)
    }
}

这样一来我可以获得与用于签名令牌的私钥相对应的公钥,并且我应该能够验证令牌。但是这失败了,给我一条错误消息说“无效签名”。我找不到失败的原因。(我已经检查过我使用jwkToPem获得的公钥是否正确)。我需要帮助来验证此令牌或找到上述代码段中的错误。

r6vfmomb

r6vfmomb1#

您不应该验证不适用于您的API的令牌。Graph API也使用一些不同的技术来验证它们的令牌,您可以在这里看到。这不是问题,因为只有Graph API本身需要能够验证令牌。
你的前端应该为你的API获取一个访问令牌。你可以验证这个令牌,然后使用代表流将其交换为一个Graph API令牌,然后你可以使用它来调用Graph API。

相关问题