oauth2.0 从Azure AD提取刷新令牌时出错

kh212irz  于 2023-03-07  发布在  其他
关注(0)|答案(1)|浏览(239)

我正在尝试从Azure AD获取刷新令牌,但收到此错误:-
数据{“错误”:“无效授权”,“错误描述”:“AADSTS 9002313:请求无效。请求格式不正确或无效。\r\n跟踪ID:4 bcb 6 e5 e-35 c1 - 4c 4 e-b184-d0ffddcc6301\r\n相关标识符:689 f7 abd-13 ef-41 f9-b 94 a-4b2269bb7c32\r\n时间戳:2023年3月3日11:15:39 Z”,“错误代码”:[9002313],“时间戳”:“2023年3月3日11:15:39 Z”,“跟踪标识”:“4 bcb 6 e5 e-35 c1 - 4c 4 e-b184-d 0 ffddcc 6301”,“相关标识”:“689 f7 abd-13 ef-41 f9-b 94 a-4 b2269 bb 7 c32”,“错误URI”:“https://login.microsoftonline.com/error?code=9002313“}
代码:

const http = require('http');
const url = require('url');
const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');

    let reqUrl = req.url;
   let code1 = reqUrl.substring(reqUrl.indexOf("?code=") + 6, reqUrl.length);
   let code=code1.split('&')[0];

        // const tokenEndpoint = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
        const clientId = <client id>;
        const redirectUri = 'http://localhost:3000/callback'; // The URL to redirect to after login
        const grantType = 'authorization_code';
        const clientSecret = <client secret>;
        
        
        const tokenRequest = {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: `grant_type=${grantType}&code=${code}&redirect_uri=${redirectUri}&client_id=${clientId}&client_secret=${clientSecret}`
        };

    let refreshToken;   
  
  fetch(tokenEndpoint, tokenRequest)
  .then(response => response.json())
  .then(data => {
    refreshToken = data.refresh_token;
    // Use the refresh token to request new access tokens as needed
  })
  .catch(error => {
    // Handle error
res.end('error');
  });

  res.end(refreshToken);
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
1sbrub3j

1sbrub3j1#

我尝试在我的环境中重现相同的结果,结果如下:

我注册了一个Azure AD应用程序并添加了API permissions,如下所示:

当我运行与您相同的代码以获取刷新令牌时,我得到了类似的错误,如下所示:

const http = require('http');
const url = require('url');
const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');

    let reqUrl = req.url;
   let code1 = reqUrl.substring(reqUrl.indexOf("?code=") + 6, reqUrl.length);
   let code=code1.split('&')[0];

        const tokenEndpoint = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
        const clientId = <client id>;
        const redirectUri = 'http://localhost:3000/callback'; // The URL to redirect to after login
        const grantType = 'authorization_code';
        const clientSecret = <client secret>;
        
        
        const tokenRequest = {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
          body: `grant_type=${grantType}&code=${code}&redirect_uri=${redirectUri}&client_id=${clientId}&client_secret=${clientSecret}`
        };

    let refreshToken;   
  
  fetch(tokenEndpoint, tokenRequest)
  .then(response => response.json())
  .then(data => {
    refreshToken = data.refresh_token;
    // Use the refresh token to request new access tokens as needed
  })
  .catch(error => {
    // Handle error
res.end('error');
  });

  res.end(refreshToken);
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
    • 答复:**

为了解决错误,我显式生成了**code值,并在获取令牌时将其作为参数包含在变量中。
我在浏览器中运行以下授权请求,并在地址栏中获得
code**值,如下所示:

https://login.microsoftonline.com/common/oauth2/v2.0/authorize? 
client_id=<appID>
&response_type=code  
&redirect_uri=http://localhost:3000/callback
&response_mode=query  
&scope= https://graph.microsoft.com/.default 
&state=12345
    • 答复:**

确保在生成刷新令牌时在scope参数中传递offline_access
现在,我运行了下面的 * modified * 代码,并在如下输出中成功获得了refresh token

const axios = require('axios');
const qs = require('qs');

const TENANT_ID = 'common';
const CLIENT_ID = 'a3bebc65-2ba6-4f07-b633-xxxxxxxxxx';
const CLIENT_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';
const AUTHORIZATION_CODE = 'paste_code_from_above_request';
const REDIRECT_URI = 'http://localhost:3000/callback';
const SCOPE = 'https://graph.microsoft.com/.default offline_access';

const TOKEN_ENDPOINT = `https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token`;

const requestBody = qs.stringify({
  code: AUTHORIZATION_CODE,
  client_id: CLIENT_ID,
  client_secret: CLIENT_SECRET,
  redirect_uri: REDIRECT_URI,
  scope: SCOPE,
  grant_type: 'authorization_code'
});

axios.post(TOKEN_ENDPOINT, requestBody, {
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})
  .then(response => {
    console.log(response.data.refresh_token);
  })
  .catch(error => {
    console.error(error);
  });
    • 答复:**

为了确认这一点,我通过Postman在以下参数中包含了上述刷新令牌,并成功获得了访问令牌,如下所示:

POST https://login.microsoftonline.com/common/oauth2/v2.0/token
client_id:<appID>
grant_type:refresh_token
scope: https://graph.microsoft.com/.default
redirect_uri: http://localhost:3000/callback
client_secret: <secret>
refresh_token: <paste_refresh_token_from_above_code_output>
    • 答复:**

相关问题