我使用asp.net Forms身份驗證來要求用戶在訪問特定頁面時登錄。我希望用戶在不活動5分鐘後再次登錄,但無論我在web.config中的表單部分的超時值中放置了什麼,用戶僅在會話狀態到期後纔會啓動。表單身份驗證超時被忽略
一個我一直在嘗試,測試包括以下配置:
<system.web>
<sessionState timeout="1" />
<authentication mode="Forms">
<forms loginUrl="~/authentication" timeout="2" slidingExpiration="true"/>
</authentication>
</system.web>
如果我登錄並保持空閒一分鐘,我問,如果我刷新頁面,重新登錄。但是,我的印象是,我應該能夠繼續工作,直到表單身份驗證超時過期。我明白,在1分鐘的時間內,對於slidingexpiration設置來更新我的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>
什麼是查看在應用程序的登錄名?通常情況下,開發人員在config表單元素中有一個名爲'Login'的視圖,在這種情況下loginUrl =「〜/ authentication/Login」。 – Sunil
視圖本身被稱爲Login.cshtml。 'loginUrl =「〜/ authentication」'設置觸發認證控制器中的Index方法,該方法在檢查ModelState是否有效後又將用戶帶到Login.cshtml視圖。登錄邏輯似乎大部分工作正常。唯一關閉的是用戶註銷並且被要求重新輸入其憑據的時間間隔。 – Bruno
可能你應該嘗試'loginUrl =「〜/ authentication/Login」'。我不知道你的應用程序需求是什麼,但是爲了將用戶重定向到登錄頁面,應該不需要檢查ModelState。但是,當您使用HttpPost調用Login操作時,即用戶提交他/她的憑據時,則需要檢查ModelState。所以我猜測,你沒有正確連接認證部分。 – Sunil