Node.js 当服务位于代理之后时,如何使用证书从Azure Active Directory获取访问令牌
我需要创建调用graph api来访问公司数据的服务。为了进行身份验证,我需要来自Azure Active Directory的JWT令牌。身份验证将使用带有签名证书的应用程序模式。我尝试使用MSAL节点机密客户端应用程序,但该服务需要使用http代理连接到internet。据我所知,MSAL节点不支持此调用,并导致库无法解析“”的地址https://login.microsoftonline.com". 如何使MSAL节点使用代理或在不使用ODMSAL的情况下获取JWT令牌?为了在没有MSAL节点的情况下从azure active directory获取JWT令牌,必须自己生成适当的JWT令牌,然后使用证书私钥对其进行签名。令牌的标头由以下字段组成:Node.js 当服务位于代理之后时,如何使用证书从Azure Active Directory获取访问令牌,node.js,azure-active-directory,jwt,msal,msal.js,Node.js,Azure Active Directory,Jwt,Msal,Msal.js,我需要创建调用graph api来访问公司数据的服务。为了进行身份验证,我需要来自Azure Active Directory的JWT令牌。身份验证将使用带有签名证书的应用程序模式。我尝试使用MSAL节点机密客户端应用程序,但该服务需要使用http代理连接到internet。据我所知,MSAL节点不支持此调用,并导致库无法解析“”的地址https://login.microsoftonline.com". 如何使MSAL节点使用代理或在不使用ODMSAL的情况下获取JWT令牌?为了在没有MSAL
{
typ: "JWT",
alg: "RS256",
kid: "156E...",
x5t: "iTYVn..."
}
{
aud: "https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token",
iss: "{clientId}",
nbf: 1617952610,
exp: 1617953210,
sub: "{clientId}",
jti: "e13efcf..."
}
- “kid”是用于签署请求的证书的指纹-下面是一个使用powershell为pfx文件获取它的好例子
- “x5t”是base64编码和净化的证书指纹
- 在末尾修剪“=”符号
- 将“/”替换为“\”
- 将“+”替换为“-”
var sanitized = s.Split('=')[0].Replace('+', '-').Replace('/', '_');
和JS代码:
var sanitized = s.split('=')[0].replace('+', '-').replace('/', '_');
令牌的有效负载由以下字段组成:
{
typ: "JWT",
alg: "RS256",
kid: "156E...",
x5t: "iTYVn..."
}
{
aud: "https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token",
iss: "{clientId}",
nbf: 1617952610,
exp: 1617953210,
sub: "{clientId}",
jti: "e13efcf..."
}
- {tenantId}和{clientId}是我们正在验证的应用程序的Azure AD数据
- “nbf”是令牌开始有效的时间,通常是生成令牌的时间。它具有unix epoch格式,是一个整数
- “exp”-unix历元格式的令牌过期时间
- “jti”-唯一的令牌标识符。它可能是随机生成的guid。每个请求都应该不同
var nbf = Math.floor(new Date().getTime() / 1000);
准备就绪时,标题和有效负载应在上序列化(带有消毒),并用“.”连接:
然后,我们需要使用证书私钥对其进行签名,使用base 64对其进行编码(使用清理),并准备clientAssertion值:
var clientAssertion = token + "." + signedToken;
作为最后一步,您可以发送请求以获取JWT令牌:
const body = new URLSearchParams();
const token = await fetch("https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token", {
agent: new HttpsProxyAgent("http://..."),
body: new URLSearchParams({
"client_assertion": clientAssertion,
"client_id": "{clientId}",
"scope": "https://graph.microsoft.com/.default"
"client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
"grant_type": "client_credentials"
}),
method: "POST",
headers: {
"content-type": "application/x-www-form-urlencoded"
}
})
.then(response => response.json().access_token);