Web API请求上的滑动会话 [英] Sliding Session on Web API Request
问题描述
更新:似乎它正在尝试在ApplyResponseGrantAsync
中写入新的cookie标头,但不能这样做,因为它 引发了标头已经发送的异常./em>
UPDATE: it appears it is trying to write the new cookie header in ApplyResponseGrantAsync
but can't because it's throwing an exception that the headers are already sent.
更新:更清晰.如何在Web API请求期间将Set-Cookie
标头添加到XHR响应中?
UPDATE: to be clearer. How do I get the Set-Cookie
header added to the XHR response during a Web API request?
TL; DR; 问题是该应用程序已通过MVC进行身份验证,但大量使用了Web API. Web API请求即使使用Authentication
属性也不会滑动会话-几乎可以肯定,因为它是cookie响应.
TL;DR; The issue is that the application is authenticated with MVC, but makes heavy use of Web API. The Web API requests do not slide the session even though they use the Authentication
attribute - almost certainly because it's a cookie response.
我有一个组合的MVC和Web API应用程序.在大多数情况下,MVC视图仅加载会发出大量Web API请求的SPA. 这很好,除了会话滑动不适用于Web API请求.
I have a combined MVC and Web API application. For the most part, the MVC views just load SPA's that make lots of Web API requests. This is fine except the session sliding does not work with Web API requests.
我可以在ApplyResponseGrantAsync
中看到CookieAuthenticationHandler
滑动会话的位置,但是我需要在每个Web API请求上强制执行该操作.
I can see where the CookieAuthenticationHandler
slides the session in ApplyResponseGrantAsync
, but I need to force that on every Web API request.
model.Properties.IssuedUtc = new DateTimeOffset?(this._renewIssuedUtc);
model.Properties.ExpiresUtc = new DateTimeOffset?(this._renewExpiresUtc);
if (this.Options.SessionStore != null && this._sessionKey != null)
{
await this.Options.SessionStore.RenewAsync(this._sessionKey, model);
ClaimsIdentity identity = new ClaimsIdentity((IEnumerable<Claim>) new Claim[1]
{
new Claim("Microsoft.Owin.Security.Cookies-SessionId", this._sessionKey)
}, this.Options.AuthenticationType);
model = new AuthenticationTicket(identity, (AuthenticationProperties) null);
}
string cookieValue = this.Options.TicketDataFormat.Protect(model);
if (model.Properties.IsPersistent)
cookieOptions.Expires = new DateTime?(this._renewExpiresUtc.ToUniversalTime().DateTime);
this.Options.CookieManager.AppendResponseCookie(this.Context, this.Options.CookieName, cookieValue, cookieOptions);
有人知道如何强制执行此操作吗?
Does anybody know how to force this?
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(15),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
},
SlidingExpiration = true,
ExpireTimeSpan = TimeSpan.FromMinutes(1)
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
推荐答案
根据CookieAuthenticationMiddleware
源,如果将CookieAuthenticationOptions
的SlidingExpiration
设置为true,则每次请求都将续订会话.您可以检查代码见自己.
According to CookieAuthenticationMiddleware
source, if you set SlidingExpiration
for CookieAuthenticationOptions
to true, your session would be renew on every request. You can check this code to see yourself.
I think I track down your problem, based on this line in order for cookie to renew, the AllowRefresh
property of AuthenticationProperties
of SignIn method should be true. I'm guessing this is your problem.
更新
这是另一种猜测,它可能会解决您的问题.基于此行一个> cookie会话将仅在其生命周期的50%过去时更新,并且当我查看代码时,我看不到任何方法可以覆盖它.我建议通过添加Middleware
来更新Cookie的变通方法,该Middleware
将在每个请求上添加SingIn
用户,从而在每个请求上创建一个新的cookie,并且该请求是否在WebAPI或MVC中都没有关系.
This is another guess, it may solve your problem. Based on this line a cookie session would renew when only 50% of its lifetime has passed and as I looked at the code I saw no way to override this. I suggest a workaround for renewing cookie by adding a Middleware
which would SingIn
user on each request, hence creating a new cookie on each request, and it doesn't matter if the request if in WebAPI or MVC.
在app.UseCookieAuthentication
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(15),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
},
SlidingExpiration = true,
ExpireTimeSpan = TimeSpan.FromMinutes(1)
});
app.Use(async (context, next) =>
{
var result = await context.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ApplicationCookie);
if (result != null)
{
result.Properties.ExpiresUtc = null;
result.Properties.IssuedUtc = null;
context.Authentication.SignIn(result.Properties, result.Identity);
}
await next();
});
基本上,您可以将SlidingExpiration
设置为false,因为此变通办法并不重要,而且以这种方式,CookieAuthentication
上的OnValidateIdentity
不能每30分钟重新加载用户声明,因为在每个版本上都会刷新IssuedUTC请求,如果需要,您必须修改此中间件并编写自定义OnValidateIdentity
basically you can set SlidingExpiration
to false, because it don't matter with this workaround and also in this way OnValidateIdentity
on CookieAuthentication
could not reload user Claims every 30 minutes, because IssuedUTC is being refreshed on each request, if you need this you have to modify this middleware and write a custom OnValidateIdentity
这篇关于Web API请求上的滑动会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!