【问题标题】:How can I sign a JWT to exchange an access token from azure active directory?如何签署 JWT 以从 azure Active Directory 交换访问令牌?
【发布时间】:2019-12-09 13:35:29
【问题描述】:

我是用 nodejs 编码的,我指的是这个文档:

https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-client-creds-grant-flow#second-case-access-token-request-with-a-certificate

正如该文档所说,我可以通过 JWT 令牌获取访问令牌。该文档说明了如何签署 JWT:

https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials

但是我找不到任何关于它的演示代码。那么如何实现它以获取访问令牌以通过 nodejs 调用 microsoft graph apis ?

感谢任何帮助,谢谢!

【问题讨论】:

标签: node.js azure azure-active-directory


【解决方案1】:

要完成整个过程,我们应该首先创建证书。我在这里使用自签名证书进行演示。

第 1 步:创建 .cer 和 .key 文件,我们将上传 .cer 到 Azure AD App 并使用 .key 文件签署我们的 JWT 令牌。

1) 通过 Powershell 创建一个密码为 123456 的自签名证书:

$cert = New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname stantest.com
$pwd = ConvertTo-SecureString -String '123456' -Force -AsPlainText
$path = 'cert:\localMachine\my\' + $cert.thumbprint 
Export-PfxCertificate -cert $path -FilePath <path of your pfx file> -Password $pwd

2) 在CMD中基于.pfx文件创建.cer文件:

openssl pkcs12 -in <path of .pfx file> -clcerts -nokeys -out <path of .cer> 

3) 在CMD中根据.pfx文件创建.key文件:

openssl pkcs12 -in <path of .pfx file> -nocerts -nodes  -out <path of .pem file>
openssl rsa -in <path of .pem file> -out <path of .key file>

最后,我们将获得以下文件:

第 2 步:将 .cer 文件上传到您的 Azure AD 应用并记下其指纹值:

第 3 步:使用下面的 nodejs 代码签署 JWT 并交换 Microsoft Graph API 的访问令牌:

var jwt = require("jsonwebtoken");
var fs = require("fs");
var uuidv1 = require('uuid/v1');
var fetch = require("node-fetch");


var tenant = "<your tenant ID/Name>";
var clientID = "<your Azure AD app ID>";
var certThumbprint = "<.cer Thumbprint value on Azure portal>";
var privateKey = fs.readFileSync("<path of your .key file>").toString();


var certOctets = certThumbprint.match(/.{1,2}/g)
var certBuffer = Buffer.alloc(certOctets.length)
    for(var i=0; i<certOctets.length; i++){
        certBuffer.writeUInt8(parseInt(certOctets[i], 16), i);
    }
//Perform base64url-encoding as per RFC7515 Appendix C
var x5t = certBuffer.toString('base64').replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');


var current = Date.now().toString().substr(0,10);

var payload= 
{
    "aud":"https://login.microsoftonline.com/"+tenant+"/oauth2/token",
    "exp": Number(current) + 3600,
    "iss":clientID,
    "jti":uuidv1(),
    "nbf":Number(current),
    "sub":clientID
}
var token = jwt.sign(payload,privateKey,{algorithm: 'RS256',header: {"x5t": x5t}})

var reqTokenBody = 
"grant_type=client_credentials&"+
"client_id="+clientID + "&" +
"resource=https://graph.microsoft.com&"+ 
"client_assertion="+ token +"&" + 
"client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer"


fetch("https://login.microsoftonline.com/hanxia.onmicrosoft.com/oauth2/token",
    {
    method: 'POST',
    headers: 
        {
        'Content-Type': 'application/x-www-form-urlencoded',

        },
    body:reqTokenBody,
    }).then((response) => response.json()).then((data) =>
        {
        console.log(JSON.stringify(data, null, 2));
        }).catch((error) =>
        {
        console.log(error);
        });

结果:

希望对您有所帮助。

【讨论】:

  • 太棒了!谢谢斯坦利,这正是我所需要的!
猜你喜欢
  • 1970-01-01
  • 2018-02-17
  • 2018-03-24
  • 2020-12-10
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2019-11-17
  • 2019-08-25
相关资源
最近更新 更多