azure auth2错误码解释表
https://learn.microsoft.com/en-us/azure/active-directory/develop/reference-error-codes
报错
AADSTS9002327: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests
故事背景
我需要调用office365 (AAD)azure的通过刷新令牌
获取新的令牌和刷新令牌。在浏览器端容器内,这没问题(因为是spa应用,走的是PKCE授权流),但在electron内由微前端mricro-app作为容器搭建的基座引入的子应用内,origin无法成功添加到请求头上。
分析
猜测的可能有2种
1、electron的请求拦截器进行了请求头的重写,导致子应用的origin写不进去。
2、由于浏览器的安全机制,当跨源时,origin不进行显示。
解决
我直接在electron的请求拦截器
进行了处理,通过给定某个请求头标记diy-origin
,在electron请求拦截器
中拦截该类请求,并手动添加origin
属性,其值则指定为diy-origin
传过来的值。
子应用代码:
const url = `https://login.microsoftonline.com/${off_tenant}/oauth2/v2.0/token`;
const params = {
client_id: off_clientId,
scope: off_scopes.join(' '),
refresh_token: refreshToken,
grant_type: 'refresh_token',
};
axios
.post(url, params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'diy-origin': 'http://localhost', // 自定义了一个diy-origin头,方便electron下的微前端基座应用拦截请求头,如果写成origin可能会被重写掉导致拦截不到
},
})
.then((res) => {
console.log('success===>', res);
if (res && res.data) {
const data = res.data;
// 获得刷新后的token和refreshToken
const opts = {
serviceId,
refreshToken: data.refresh_token,
accessToken: data.access_token,
expiresIn: data.expires_in,
email,
};
console.log('使用刷新令牌从office获取新的访问令牌', data, opts);
updateBindEmailInfo(opts);
}
});
桌面端electron应用拦截请求的代码:
interceptorsRequest() {
session.defaultSession.webRequest.onBeforeSendHeaders(
async (detail: Electron.OnBeforeSendHeadersListenerDetails, callback) => {
this.requestMap[detail.id] = pick(detail, [
'id',
'url',
'method',
'resourceType',
'timestamp',
'requestHeaders'
]);
if (detail.requestHeaders['diy-origin']) {
callback({
requestHeaders: {
...detail.requestHeaders,
origin: detail.requestHeaders['diy-origin']
}
});
}
callback({ responseHeaders: headers });
});
}