我们有一个ASP.NET MVC 5 web应用程序,我们使用AngularJS从MVC控制器(不是ApiControllers)获取数据。它的身份验证使用cookie身份验证与默认的到期时间1小时后连接到Azure AD。当ajax调用失败时在后端更新访问令牌
该应用程序是SPA。一旦用户登录,他们不会导航到其他页面,而只使用ajax($ http)调用。
到目前为止,我们扩展了Startup.Configuration()中的RedirectToIdentityProvider方法,以识别ajax调用,并在令牌过期时将错误403返回给客户端。这样,我们避免重定向到权威页面并获得CORS错误。
此外,我们在同一类的AuthorizationCodeReceived
中实现了持久令牌缓存助手TokenCache
(命名空间Microsoft.IdentityModel.Clients.ActiveDirectory
)。
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = ConfigurationHelper.ClientId,
Authority = ConfigurationHelper.AzureAdAuthorizationUri,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = true
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
AuthorizationCodeReceived = (context) =>
{
var code = context.Code;
ClientCredential credential = new ClientCredential(ConfigurationHelper.ClientId, ConfigurationHelper.AppKey);
String UserObjectId = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext = new AuthenticationContext(ConfigurationHelper.AzureAdAuthorizationUri, new InMemoryTokenCache(UserObjectId));
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, ConfigurationHelper.AzureAdGraphResourceUri);
return Task.FromResult(0);
},
RedirectToIdentityProvider = (context) =>
{
if (IsAjaxRequest(context.Request))
{
context.Response.StatusCode = 401; // for web API only!
context.Response.Headers.Remove("Set-Cookie");
context.State = NotificationResultState.HandledResponse;
}
else
{
string appBaseUrl = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase;
context.ProtocolMessage.RedirectUri = appBaseUrl + "/" + context.Request.QueryString;
context.ProtocolMessage.PostLogoutRedirectUri = appBaseUrl;
}
return Task.FromResult(0);
},
AuthenticationFailed = (context) =>
{
// Suppress the exception
context.HandleResponse();
return Task.FromResult(0);
}
}
});
}
InMemoryTokenCache
是我们的包装器TokenCache
IsAjaxRequest
是识别Ajax调用的函数。其余的都是ASP.NET MVC 5模板的标准。
我们的问题是,当用户访问令牌到期时,我们要刷新它,并继续使用,无需将用户重定向到一个登录屏幕或返回403客户端去。我们在哪里以及如何做到这一点?
这是一个选项,但该理论认为我不应该这样做。刷新令牌仅用于获取访问令牌,并且仅在用户稍后过期后请求某些内容。 –
我已经添加了另一个解决方案,希望它有帮助;) –