如何签名JWT以交换来自Azure活动目录的访问令牌? [英] How can I sign a JWT to exchange an access token from azure active directory?

查看:84
本文介绍了如何签名JWT以交换来自Azure活动目录的访问令牌?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过nodejs进行编码,并且我引用此文档:

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

第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 =<您的租户ID/名称>";var clientID =<您的Azure AD应用程序ID>";var certThumbprint =< .cer Azure门户上的拇指指纹值">;var privateKey = fs.readFileSync(< .key文件的路径>").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);}//按照RFC7515附录C执行base64url-encodingvar x5t = certBuffer.toString('base64').replace(/=/g,``).replace(/\ +/g,'-').replace(/\//g,'_');var current = Date.now().toString().substr(0,10);var有效负载={"aud":"https://login.microsoftonline.com/" + tenant +"/oauth2/token","exp":数字(当前)+ 3600,"iss":clientID,"jti":uuidv1(),"nbf":数字(当前),"sub":clientID}var token = jwt.sign(payload,privateKey,{algorithm:'RS256',header:{"x5t":x5t}})var reqTokenBody ="grant_type = client_credentials&" +"client_id =" + clientID +&"+资源= https://graph.microsoft.com&" +"client_assertion =" +令牌+&"+"client_assertion_type = urn:ietf:params:oauth:client-assertion-type:jwt-bearer"fetch("https://login.microsoftonline.com/hanxia.onmicrosoft.com/oauth2/token",{方法:"POST",标头:{内容类型":应用程序/x-www-form-urlencoded",},正文:reqTokenBody,}).then((response)=> response.json()).then((data)=>{console.log(JSON.stringify(data,null,2));}).catch((错误)=>{console.log(错误);}); 

结果:

希望它会有所帮助.

I am coding by nodejs and I am referring to this doc :

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

As this doc said , I can get an access token by a JWT token . This doc indicated how to sign a JWT :

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

but I can't find any demo code about it.So how can I implement it to get an access token to call microsoft graph apis by nodejs ?

Any assistance is appreciated, thanks !

解决方案

To go through this whole process , we should create certs first. I use self-signed certs for demo here .

Step 1 : Create .cer and .key files, we will upload .cer to Azure AD App and use .key file to sign our JWT tokens.

1) Create a self signed cert which password is 123456 by Powershell :

$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) Create .cer file based on .pfx file in CMD:

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

3) Create .key file based on .pfx file in CMD:

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>

Finally , we will get files below :

STEP 2 : Upload .cer file to your Azure AD app and note its Thumbprint value:

STEP 3 : Use the nodejs code below to sign a JWT and exchange an access token for Microsoft Graph APIs :

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);
        });

Result :

Hope it helps.

这篇关于如何签名JWT以交换来自Azure活动目录的访问令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆