英文:
B2C token lifetime does not work and new access token cannot pass APIM
问题
我有我的ReactJS单页应用程序,我的Web API托管在Azure虚拟机上。我将APIM放在虚拟机前面,APIM根据B2C验证令牌进行授权。
在B2C用户流中,我将令牌的生存期设置为5分钟;
在SPA中,当我第一次登录时,它运行良好,我可以调用Web API而没有问题。但是,稍后我遇到了2个问题:
-
即使我将令牌的生存期设置为5分钟,但在5分钟后令牌仍然有效;它直到大约13或14分钟后才变为无效;太奇怪了;
-
在令牌刷新后,新的访问令牌无法通过APIM;它返回401错误;我可以验证新的令牌位于会话存储中;刷新过程成功。
以下是我最初用于登录的loginRequest
:
export const loginRequest = {
scopes: ['openid', 'profile'],
};
以下是我用于刷新令牌的代码:
export const msalInstance = new PublicClientApplication(msalConfig);
export const GetAzureB2CAccessToken = async () => {
const activeAccount = msalInstance.getActiveAccount(); // 仅当您在其他地方调用setActiveAccount API时,此值才会返回非空值
const accounts = msalInstance.getAllAccounts();
if (!activeAccount && accounts.length === 0) {
/*
* 用户未登录。抛出错误或等待用户登录。
* 请不要在MsalProvider的上下文之外尝试登录用户。
*/
throw new Error('用户未登录');
}
var request = {
scopes: [
'openid',
'profile',
'https://devjohn1.onmicrosoft.com/123qwe-19eb-fff-qqqq-123qwe123qwe/johnapp_api',
],
account: activeAccount || accounts[0],
};
const tokenResponse = await msalInstance.acquireTokenSilent(request);
return tokenResponse.accessToken;
};
有什么想法吗?
英文:
I have my reactJS SPA and I have my web api hosted in an Azure VM. I put APIM in front of the VM and the APIM validates token against B2C for authorization.
In the B2C User Flow, I have set the token lifetime to 5 minutes;
In the SPA, when I first log in, it works well and I can make calls to the web APIs with no problem. However, later I have 2 problems:
-
Even though I set the token lifetime to 5 minutes, it is still valid after 5 minutes; It only becomes invalid at around 13 or 14 minutes; So weird;
-
After the tokens are refreshed, the new access token cannot pass APIM; it returns a 401 error; I can verify that the new tokens are in position in the session storage; the refresh process is successful
Here is the loginRequest
I used at first to sign in:
export const loginRequest = {
scopes: ['openid', 'profile'],
};
Here is the code I use to refresh token:
export const msalInstance = new PublicClientApplication(msalConfig);
export const GetAzureB2CAccessToken = async () => {
const activeAccount = msalInstance.getActiveAccount(); // This will only return a non-null value if you have logic somewhere else that calls the setActiveAccount API
const accounts = msalInstance.getAllAccounts();
if (!activeAccount && accounts.length === 0) {
/*
* User is not signed in. Throw error or wait for user to login.
* Do not attempt to log a user in outside of the context of MsalProvider
*/
throw new Error('user is not signed in;');
}
var request = {
scopes: [
'openid',
'profile',
'https://devjohn1.onmicrosoft.com/123qwe-19eb-fff-qqqq-123qwe123qwe/johnapp_api',
],
account: activeAccount || accounts[0],
};
const tokenResponse = await msalInstance.acquireTokenSilent(request);
return tokenResponse.accessToken;
};
Any ideas?
答案1
得分: 2
我创建了一个Azure AD B2C用户流,并将令牌生存期设置为5分钟,如下所示:
现在,当我通过Postman生成令牌时,令牌生存期设置为5分钟,如下所示:
https://rukb2c.b2clogin.com/rukb2c.onmicrosoft.com/B2C_1_testruk/oauth2/v2.0/token
client_id:ClientID
scope:https://rukb2c.onmicrosoft.com/ClientID/test.read offline_access openid
grant_type:authorization_code
code_verifier:S256
code:code
即使我将令牌生存期设置为5分钟,它仍然在5分钟后有效;它只在大约13或14分钟后失效;太奇怪了
如果令牌未根据令牌生存期策略过期,那么可能是由于时钟偏差,其默认值为5分钟。
根据 @Kid_Learning_C 的评论,如果要使令牌在精确时间过期,请将 ClockSkew
设置为零。
services.AddAuthentication("Bearer").AddJwtBearer("Bearer", options =>
{
options.Authority = "https://xxxx";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
});
参考资料:
oauth - 时钟偏差和令牌 - Stack Overflow 由 rajquest
英文:
I created an Azure AD B2C User flow and set the token lifetime to 5 minutes like below:
Now, when I generated the tokens via Postman and the token lifetime is set for 5 minutes like below:
https://rukb2c.b2clogin.com/rukb2c.onmicrosoft.com/B2C_1_testruk/oauth2/v2.0/token
client_id:ClientID
scope:https://rukb2c.onmicrosoft.com/ClientID/test.read offline_access openid
grant_type:authorization_code
code_verifier:S256
code:code
> Even though I set the token lifetime to 5 minutes, it is still valid after 5 minutes; It only becomes invalid at around 13 or 14 minutes; So weird
If the token is not expiring based on the token lifetime policy, then it might be due to clock skew and the default value is 5 minutes.
As per the comments by @Kid_Learning_C, Set ClockSkew
to zero if you want token to expire at the precise time.
services.AddAuthentication("Bearer").AddJwtBearer("Bearer", options =>
{
options.Authority = "https://xxxx";
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
});
Reference:
oauth - Clock skew and tokens - Stack Overflow by rajquest
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论