从 Microsoft Teams 获取 SSO 身份验证令牌时出现问题
Problem with getting SSO Auth token from Microsoft Teams
我想从 Microsoft 团队获取访问令牌,当在 postman 中使用相同的数据执行它时,它完美地工作,当在 React 应用程序中发出 post 请求时,它确实不工作。
这是我的代码:
useEffect(() => {
debugger;
if (inTeams === true) {
microsoftTeams.authentication.getAuthToken({
successCallback: (result) => {
console.log(result);
const serviceRequest: any = {
client_id: "[client_id]",
client_secret: "[client_secret]",
requested_token_use: "on_behalf_of",
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
scope:
"[scope]",
assertion: result,
};
httpClient.GetAuthenticationToken(serviceRequest).then((res) => {
console.log(res);
});
var querystring = require("querystring");
//...
var asd = querystring.stringify(serviceRequest);
console.log(asd);
axios
.post(
"https://login.microsoftonline.com/common/oauth2/v2.0/token",
asd,
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}
)
.then(function (response) {
console.log(response);
});
microsoftTeams.appInitialization.notifySuccess();
},
failureCallback: function (error) {
console.log(error);
},
});
} else {
setEntityId("Not in Microsoft Teams");
}
}, [inTeams]);
这是我发的(在网络上找到的,'[]'里的字段是我替换的,因为隐私)
client_id=[client_id]&client_secret=[client_secret]&requested_token_use=on_behalf_of&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&scope=[scope]&assertion=[assertion]
这是我得到的错误:
这是网络预览版:
AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type.\r\nTrace ID: ef9c5d80-13d0-4001-898b-7206f4663b00\r\nCorrelation ID: 2c0d0ece-3ce5-4ee6-9cdf-8966f66cee2f\r\nTimestamp: 2022-04-01 10:06:19Z
--------------------------------
更新:
多亏了答案:)
我制作了一个获取 SSO 令牌并将其交换为 OBO 令牌的后端方法。
这是代码:
public static async Task<string> ExchangeForOBOToken(ExchangeOBORequest request)
{
var contentData = new Dictionary<string, string>();
contentData.Add("client_id", request.client_id);
contentData.Add("client_secret", request.client_secret);
contentData.Add("requested_token_use", request.requested_token_use);
contentData.Add("grant_type", request.grant_type);
contentData.Add("scope", request.scope);
contentData.Add("assertion", request.assertion);
using (var httpClient = new HttpClient())
{
using (var content = new FormUrlEncodedContent(contentData))
{
content.Headers.Clear();
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
HttpResponseMessage response = await httpClient.PostAsync("https://login.microsoftonline.com/common/oauth2/v2.0/token", content);
var res= await response.Content.ReadAsStringAsync();
return res;
}
}
}
我只是从前端使用所有数据和 return OBO 令牌调用它:)
所以上面有一堆要点:
您实际上没有说明您需要令牌的用途。据推测,您希望 SSO 令牌能够调用 Graph,这就是为什么您想将其交换为“代表”(OBO) 令牌的原因 - 请确认
您不希望在您的客户端代码中进行 OBO 令牌交换 - 这只意味着在服务器端发生,这样这些宝贵的令牌就不会泄漏到攻击者。在 this video and this blog post.
中查看更多信息
一旦您的 OBO 部分移出到您的后端,您的代码看起来会简单得多,如下所示:
useEffect(() => {
debugger;
if (inTeams === true) {
microsoftTeams.authentication.getAuthToken({
successCallback: (result) => {
// make your call here to your backend, which will in turn: (A) get the OBO token and (B) use it to call whatever you want on Graph.
},
failureCallback: function (error) {
console.log(error);
},
});
} else {
setEntityId("Not in Microsoft Teams");
}
}, [inTeams]);
我想从 Microsoft 团队获取访问令牌,当在 postman 中使用相同的数据执行它时,它完美地工作,当在 React 应用程序中发出 post 请求时,它确实不工作。
这是我的代码:
useEffect(() => {
debugger;
if (inTeams === true) {
microsoftTeams.authentication.getAuthToken({
successCallback: (result) => {
console.log(result);
const serviceRequest: any = {
client_id: "[client_id]",
client_secret: "[client_secret]",
requested_token_use: "on_behalf_of",
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
scope:
"[scope]",
assertion: result,
};
httpClient.GetAuthenticationToken(serviceRequest).then((res) => {
console.log(res);
});
var querystring = require("querystring");
//...
var asd = querystring.stringify(serviceRequest);
console.log(asd);
axios
.post(
"https://login.microsoftonline.com/common/oauth2/v2.0/token",
asd,
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}
)
.then(function (response) {
console.log(response);
});
microsoftTeams.appInitialization.notifySuccess();
},
failureCallback: function (error) {
console.log(error);
},
});
} else {
setEntityId("Not in Microsoft Teams");
}
}, [inTeams]);
这是我发的(在网络上找到的,'[]'里的字段是我替换的,因为隐私)
client_id=[client_id]&client_secret=[client_secret]&requested_token_use=on_behalf_of&grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&scope=[scope]&assertion=[assertion]
这是我得到的错误:
这是网络预览版:
AADSTS9002326: Cross-origin token redemption is permitted only for the 'Single-Page Application' client-type.\r\nTrace ID: ef9c5d80-13d0-4001-898b-7206f4663b00\r\nCorrelation ID: 2c0d0ece-3ce5-4ee6-9cdf-8966f66cee2f\r\nTimestamp: 2022-04-01 10:06:19Z
--------------------------------
更新: 多亏了答案:)
我制作了一个获取 SSO 令牌并将其交换为 OBO 令牌的后端方法。 这是代码:
public static async Task<string> ExchangeForOBOToken(ExchangeOBORequest request)
{
var contentData = new Dictionary<string, string>();
contentData.Add("client_id", request.client_id);
contentData.Add("client_secret", request.client_secret);
contentData.Add("requested_token_use", request.requested_token_use);
contentData.Add("grant_type", request.grant_type);
contentData.Add("scope", request.scope);
contentData.Add("assertion", request.assertion);
using (var httpClient = new HttpClient())
{
using (var content = new FormUrlEncodedContent(contentData))
{
content.Headers.Clear();
content.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
HttpResponseMessage response = await httpClient.PostAsync("https://login.microsoftonline.com/common/oauth2/v2.0/token", content);
var res= await response.Content.ReadAsStringAsync();
return res;
}
}
}
我只是从前端使用所有数据和 return OBO 令牌调用它:)
所以上面有一堆要点:
您实际上没有说明您需要令牌的用途。据推测,您希望 SSO 令牌能够调用 Graph,这就是为什么您想将其交换为“代表”(OBO) 令牌的原因 - 请确认
您不希望在您的客户端代码中进行 OBO 令牌交换 - 这只意味着在服务器端发生,这样这些宝贵的令牌就不会泄漏到攻击者。在 this video and this blog post.
中查看更多信息一旦您的 OBO 部分移出到您的后端,您的代码看起来会简单得多,如下所示:
useEffect(() => {
debugger;
if (inTeams === true) {
microsoftTeams.authentication.getAuthToken({
successCallback: (result) => {
// make your call here to your backend, which will in turn: (A) get the OBO token and (B) use it to call whatever you want on Graph.
},
failureCallback: function (error) {
console.log(error);
},
});
} else {
setEntityId("Not in Microsoft Teams");
}
}, [inTeams]);