Web API请求上的滑动会话 [英] Sliding Session on Web API Request

查看:73
本文介绍了Web API请求上的滑动会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:似乎它正在尝试在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源,如果将CookieAuthenticationOptionsSlidingExpiration设置为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆