![](/img/trans.png)
[英]Retrieve 2 Access Tokens on Interactive Authentication in Azure AD
[英]Refreshing OKTA Access Tokens from background
我有 .NET 5.0 Blazor 服务器应用程序和 openiD OKTA 已集成。 我们的访问令牌将在 1 小时后过期,之后需要刷新它。 我在 UI 中使用 cookie,在后端使用 accesstoken。 我目前为访问令牌刷新所做的是,在 1 小时后,路由到 controller 操作以手动刷新令牌,如下所示。
正如我所提到的,我使用 cookie 并验证每次都会触发的 CookieAuthenticationEvent 中的令牌。 下面是中间件部分配置。
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, displayName:
"epd_local",
options =>
{
options.Cookie.Name = "epd_local";
options.Cookie.HttpOnly = false;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Cookie.IsEssential = true;
options.Events = new CookieAuthenticationEvents
{
// this event is fired everytime the cookie has been validated by the cookie middleware,
// so basically during every authenticated request
// the decryption of the cookie has already happened so we have access to the user claims
// and cookie properties - expiration, etc..
OnValidatePrincipal = context =>
{
//HERE VALIDATING TOKEN
经过上述验证,如果失败,路由到下面的端点。
public IActionResult Refresh([FromQuery] string returnUrl)
{
var authProps = new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = <<new time>>,
RedirectUri = returnUrl ?? GlobalVariables.OktaCallBackURI // Url.Content("~")
};
return Challenge(authProps);
}
这里的问题是这种方法会刷新屏幕并且会丢失当时添加的条目。 有没有更好的方法在不影响屏幕的情况下在后台刷新访问令牌? 身份验证后,我也获得了刷新令牌和访问令牌,但不确定这对这里有何帮助?
我通过在启动 class 中注册 OpenId 事件来改进实现。在事件处理程序 OnTokenValidated 中,要设置的主要属性是context.Properties.AllowRefresh = true 。 设置此属性后令牌自动刷新,无需手动路由。
options.Events = new OpenIdConnectEvents
{
// this makes signout working
OnRedirectToIdentityProviderForSignOut = OnRedirectToIdentityProviderForSignOut,
OnRedirectToIdentityProvider = OnRedirectToIdentityProvider,
OnRemoteSignOut = context =>
{
context.Response.Redirect("GlobalVariables.OktaCallBackURI +/logout");
context.HandleResponse();
return Task.CompletedTask;
},
OnRemoteFailure = context =>
{
context.HandleResponse();
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
context.HandleResponse();
return Task.CompletedTask;
},
OnAccessDenied = context =>
{
context.HandleResponse();
return Task.CompletedTask;
},
OnTokenValidated = context =>
{
try
{
if (context is not null && context.Principal is not null && context.Principal.Identity is not null)
{
var identity = (ClaimsIdentity)context.Principal.Identity;
List<Claim> addToken = new();
if (context?.TokenEndpointResponse is not null && context?.TokenEndpointResponse?.AccessToken is not null)
{
addToken.Add(new Claim("access_token", context?.TokenEndpointResponse?.AccessToken));
}
if (context?.TokenEndpointResponse is not null && context?.TokenEndpointResponse?.RefreshToken is not null)
{
addToken.Add(new Claim("refresh_token", context?.TokenEndpointResponse?.RefreshToken));
}
if (addToken.Count > 0)
{
identity.AddClaims(addToken);
}
// so that we don't issue a session cookie but one with a fixed expiration
context.Properties.IsPersistent = true;
context.Properties.AllowRefresh = true;
// align expiration of the cookie with expiration of the
var accessToken = new JwtSecurityToken(context.TokenEndpointResponse.AccessToken);
}
else
{
//hk todo
//redirect
}
}
catch
{
}
return Task.CompletedTask;
},
OnTicketReceived = context =>
{
// If your authentication logic is based on users then add your logic here
return Task.CompletedTask;
},
//HK save for later
OnSignedOutCallbackRedirect = context =>
{
context.Response.Redirect("~/");
context.HandleResponse();
return Task.CompletedTask;
},
OnUserInformationReceived = context =>
{
//IHttpContextAccessor httpContextAccessor;
RegisterUser(context);
return Task.CompletedTask;
},
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.