表单身份验证超时被忽略

布鲁诺

我正在使用asp.net表单身份验证来要求用户在访问特定页面时登录。我希望用户在闲置5分钟后必须再次登录,但是无论我在web.config的“表单”的“超时值”部分中输入什么内容,用户都只能在会话状态过期后才能启动。

我尝试过的测试之一涉及此配置:

<system.web>   
<sessionState timeout="1" />
  <authentication mode="Forms">
      <forms loginUrl="~/authentication" timeout="2" slidingExpiration="true"/>
  </authentication>
</system.web>

如果我登录并闲置一分钟,则刷新页面时,系统会要求我再次登录。但是,我的印象是,在表单身份验证超时到期之前,我应该能够继续工作。我知道,在1分钟标记处,对于slideExpiration设置来更新我的cookie来说为时已晚,但是在cookie实际失效之前,我还应该再等一分钟。

如果我删除了Sessiontate超时部分,则在两分钟后不要求我登录。要求我重新登录需要很长时间(大约30分钟)。对我来说,这听起来像只在sessionState到期时才要求重新登录。

我在这里想念什么吗?

这是所涉及的控制器和方法的基本布局。首先,用户尝试转到“招聘人员”页面:

public class HireController : Controller
{
    [Authorize]
    public ActionResult Recruiter()
    {
      //do stuff after we've been authorized to access this page
    }
}

因为需要授权用户,所以他们被重定向到身份验证控制器中的登录页面:

public class AuthenticationController : BaseAuthenticationController
{
    private readonly IAuthenticationService AuthenticationService;
    public AuthenticationController(IAuthenticationService authService)
        : base(authService)
    {
        AuthenticationService = authService;
    }
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Index(string returnUrl)
    {
        var special= false;
        return View("~/Views/Login/Login.cshtml", new LoginModel(special) { ReturnUrl = returnUrl });
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(LoginCredentials credentials, string returnUrl)
    {
        try
        {
            if (!ModelState.IsValid)
            {
                throw new ApplicationException(GeneralError);
            }

            base.DoLogin(credentials.Username, credentials.Password);
        }
        catch (Exception ex)
        {
            string message = (ex is ApplicationException) ? ex.Message : GeneralError;
            ModelState.AddModelError("", message);
            return View("~/Views/Login/Login.cshtml", new LoginModel { Username = credentials.Username, ReturnUrl = returnUrl });
        }
        return RedirectToLocal(returnUrl);

    }

    private ActionResult RedirectToLocal(string returnUrl)
    {
        if (Url.IsLocalUrl(returnUrl))
        {
            return Redirect(returnUrl);
        }
        if (User.Identity != null && User.Identity.IsAuthenticated)
        {
            return RedirectToAction("Recruiter", "Hire");
        }
        return RedirectToAction("Recruiter", "Hire");
    }
}

这是BaseAuthenticationController类:

  public class BaseAuthenticationController : Controller
{
    private readonly IAuthenticationService AuthenticationService;
    protected const string GeneralError = "Login failure please try again";

    public BaseAuthenticationController(IAuthenticationService authService)
    {
        AuthenticationService = authService; 
    }

    public void DoLogin(string username, string password)
    {
        AuthenticationService.Login(username, password);
    }
}

这是具体的IAuthenticationService类:

 public class WebAuthenticationService : IAuthenticationService
{
    private const string InvalidError = "Invalid User Credentials Please try again";
    private const string LockoutError = "You have been locked out of the Hiring Center. You will receive an email shortly once your password has been reset.";
    readonly string uri = ConfigurationManager.AppSettings["HiringLoginApiBaseUrl"];
    private readonly ISecurityContext SecurityContext; 

    public WebAuthenticationService(ISecurityContext securityContext)
    {
        SecurityContext = securityContext; 
    }

    private LoginResult GetUserLogin(string username, string password)
    {
        using (var httpClient = new HttpClient())
        {
            httpClient.BaseAddress = new Uri(uri);
            var content = new FormUrlEncodedContent(new[] 
            {
                new KeyValuePair<string, string>("username", username),
                new KeyValuePair<string, string>("password", password)
            });
            var postResult = httpClient.PostAsync("/api/Login/Post", content).Result;                
            var loginResult = postResult.Content.ReadAsAsync<LoginResult>().Result;

            return loginResult;
        }
    }

    public MembershipProvider AuthenticationProvider
    {
        get { return Membership.Provider; }
    }

    public void Login(string userName, string password)
    {
        var loginResult = this.GetUserLogin(userName, password);
        if (!loginResult.IsValid)
        {
            throw new ApplicationException(InvalidError);
        }

        if (loginResult.IsLockedOut)
        {
            throw new ApplicationException(LockoutError);
        }

        // Maintain the location
        IUser current = SecurityContext.Current;

        SecurityContext.SetCurrent(User.CreateAuthorized(userName, current.Location, current.Preferences));
        FormsAuthentication.SetAuthCookie(userName, false);

    }
}

对于WebAuthenticationService类中的以下行,我不太清楚:

SecurityContext.SetCurrent(User.CreateAuthorized(userName, current.Location, current.Preferences));

SetCurrent()方法的定义如下:

 public class HttpSecurityContext : ISecurityContext
{
    public static string SECURITY_CONTEXT_KEY = "SECURITY_CONTEXT";

    public IUser Current
    {
        get
        {
            IUser user = HttpContext.Current.User as IUser;
            if (user == null)
            {
                throw new ApplicationException("Context user is invalid;");
            }
            return user;
        }
    }

    public void SetCurrent(IUser user)
    {
        HttpContext.Current.User = user;
    }
}

Web.Config成员资格提供程序:

      <membership>
      <providers>
          <clear />
          <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=asdfasf" connectionStringName="mydb" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="3" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/" />
      </providers>
     </membership>
布鲁诺

我找到了所有问题的起因。我在global.asax中找到了一堆可操纵用户会话并实质上覆盖表单身份验证的代码。该代码在对服务器的每个请求上运行,并且只要用户仍在会话中进行身份验证,就可以使用户保持登录状态。这意味着即使表单auth cookie过期(确实如此!),用户仍将保持登录状态。我猜测以前的开发人员从表单auth开始,然后出于某种原因决定编写自己的东西。我们决定更改会话超时,以便在5分钟(而不是默认的20分钟)后注销用户。

这是来自global.asax的一些代码,这些代码几乎使我秃头:

 protected void Application_PreRequestHandlerExecute()
    {
        HttpSessionState session = HttpContext.Current.Session;
        if (session == null)
            return;

        IUser user = (session[HttpSecurityContext.SECURITY_CONTEXT_KEY] as IUser) ?? CreateUser();
        securityContext.SetCurrent(user);
    }

    protected void Application_PostRequestHandlerExecute()
    {
        HttpSessionState session = HttpContext.Current.Session;
        if (session == null) return;

        session[HttpSecurityContext.SECURITY_CONTEXT_KEY] = securityContext.Current;
    }

 private IUser CreateUser()
    {
        IUserLocation location = LocateUser();
        IUser user = Common.Security.User.CreateAnonymous(location);
        SetupUserPreferences(user);
        return user;
    }

这是我们在web.config中为会话超时所做的更改:

<system.web>
    <sessionState timeout="5"/>
</system.web>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类常见问题

表单身份验证超时与sessionState超时

来自分类Dev

IIS会话超时和表单身份验证循环

来自分类Dev

.NET表单身份验证在超时之前注销用户

来自分类Dev

表单身份验证登录超时推迟

来自分类Dev

JSF表单身份验证+ OAuth

来自分类Dev

是什么导致MVC3中的会话/表单身份验证超时

来自分类Dev

表单身份验证票未验证

来自分类Dev

禁用WCF调用的表单身份验证

来自分类Dev

ClaimsAuthenticationManager与IAuthenticationFilter与OWIN表单身份验证

来自分类Dev

表单身份验证:“无法联系服务器”

来自分类Dev

桥接表单身份验证和OAUTH

来自分类Dev

MVC 4表单身份验证(无限登录)

来自分类Dev

表单身份验证Cookie不会过期

来自分类Dev

Owin使用外部表单身份验证Cookie

来自分类Dev

MVC4表单身份验证+ AJAX操作

来自分类Dev

表单身份验证:角色(MVC 4)C#

来自分类Dev

HTML到PDF和表单身份验证

来自分类Dev

通过异步请求实现表单身份验证

来自分类Dev

C#WebClient表单身份验证

来自分类Dev

尽管测试成功,表单身份验证仍失败

来自分类Dev

表单身份验证和Active Directory

来自分类Dev

禁用WCF调用的表单身份验证

来自分类Dev

AngularJS和Web API表单身份验证

来自分类Dev

通过异步请求实现表单身份验证

来自分类Dev

HTML到PDF和表单身份验证

来自分类Dev

跨网站共享的表单身份验证

来自分类Dev

表单身份验证-以编程方式注销用户

来自分类Dev

如何正确注销表单身份验证

来自分类Dev

表单身份验证:如何处理未经授权的身份验证用户