Ich benutze die asp.net-Formularauthentifizierung, damit Benutzer sich beim Besuch einer bestimmten Seite anmelden müssen. Ich möchte, dass sich die Benutzer nach 5 Minuten Inaktivität wieder einloggen müssen, aber unabhängig davon, was ich im Timeout-Wert des forms-Abschnitts in web.config eingegeben habe, wird der Benutzer erst nach Ablauf des Sitzungsstatus gestartet.Zeitlimitüberschreitung bei Formularauthentifizierung
Einer der Tests, die ich versucht habe, beinhaltet diese Konfiguration:
<system.web>
<sessionState timeout="1" />
<authentication mode="Forms">
<forms loginUrl="~/authentication" timeout="2" slidingExpiration="true"/>
</authentication>
</system.web>
Wenn ich mich einloggen und bleiben Leerlauf für eine Minute, die ich gefragt bin wieder anmelden, wenn ich die Seite aktualisieren. Ich hatte jedoch den Eindruck, dass ich weiterarbeiten könnte, bis das Zeitlimit für die Formularauthentifizierung abgelaufen ist. Ich verstehe, dass es bei der 1-Minuten-Marke zu spät für die Einstellung gleitendeErlaubnis wäre, mein Cookie zu erneuern, aber ich sollte noch eine Minute warten, bevor das Cookie tatsächlich abläuft.
Wenn ich den Sessiontate-Timeout-Bereich entferne, werde ich nach zwei Minuten nicht aufgefordert, mich einzuloggen. Es dauert eine lange Zeit (wahrscheinlich 30 Minuten), bevor ich aufgefordert werde, mich wieder anzumelden. Das klingt für mich so, als ob ich mich nur anmelde, wenn der sessionState abläuft.
Fehle ich hier etwas?
Hier ist das grundlegende Layout der beteiligten Controller und Methoden. Zuerst versucht der Benutzer auf die Recruiter Seite zu gehen:
public class HireController : Controller
{
[Authorize]
public ActionResult Recruiter()
{
//do stuff after we've been authorized to access this page
}
}
Da der Benutzer autorisiert werden muss sie auf die Anmeldeseite in dem Authentifizierungs-Controller weitergeleitet werden:
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");
}
}
Hier ist die BaseAuthenticationController Klasse :
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);
}
}
Hier ist die konkrete IAuthenticationService Klasse:
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);
}
}
ich nicht ganz klar bin, was der Punkt der folgenden Zeile ist in der WebAuthenticationService Klasse:
SecurityContext.SetCurrent(User.CreateAuthorized(userName, current.Location, current.Preferences));
die SetCurrent() -Methode wie folgt definiert ist:
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 Mitgliedschafts-Provider:
<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>
Was ist der Name der Ansicht für die Anmeldung in der App? Normalerweise haben Entwickler eine Ansicht mit dem Namen 'Login', in diesem Fall' loginUrl = "~/authentication/Login" 'in der Konfigurationsdatei für forms. – Sunil
Die Ansicht selbst heißt Login.cshtml. Die Einstellung "loginUrl =" ~/authentication "" löst die Index-Methode im Authentifizierungs-Controller aus, die wiederum den Benutzer in die Login.shtml-Ansicht versetzt, nachdem überprüft wurde, ob der ModelState gültig ist. Die Login-Logik scheint größtenteils in Ordnung zu sein. Die einzige Ausnahme ist das Intervall, nach dem der Benutzer abgemeldet wird und aufgefordert wird, seine Anmeldeinformationen erneut einzugeben. – Bruno
Vielleicht sollten Sie versuchen mit 'loginUrl =" ~/authentication/Login "'. Ich weiß nicht, was Ihre App-Anforderungen sind, aber um einen Benutzer zur Anmeldeseite umzuleiten, sollte ModelState nicht überprüft werden. Wenn Sie jedoch die Anmeldeaktion mit HttpPost aufrufen, d. H. Wenn der Benutzer seine Anmeldeinformationen übermittelt, müssen Sie ModelState überprüfen. Ich vermute, Sie haben den Authentifizierungsteil nicht richtig verdrahtet. – Sunil