/// <summary> /// Raises <see cref="OnAuthenticationRequired"/>. /// </summary> /// <param name="args"></param> private void OnAuthenticationRequired(AuthenticationRequiredEventArgs args) { if (AuthenticationRequired != null) { AuthenticationRequired(this, args); } }
public void AuthenticationRequiredEventArgs_Initialises_To_Known_State_And_Properties_Work() { AuthenticationRequiredEventArgs args = new AuthenticationRequiredEventArgs("Abc", "Def"); Assert.AreEqual("Abc", args.User); Assert.AreEqual("Def", args.Password); TestUtilities.TestProperty(args, r => r.IsAuthenticated, false); TestUtilities.TestProperty(args, r => r.IsHandled, false); }
/// <summary> /// Handles the authentication events from the server. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void Server_AuthenticationRequired(object sender, AuthenticationRequiredEventArgs args) { lock (_AuthenticationSyncLock) { if (!args.IsHandled && WebServer.AuthenticationScheme == AuthenticationSchemes.Basic) { args.IsAuthenticated = args.User != null && args.User.Equals(_BasicAuthenticationUser, StringComparison.OrdinalIgnoreCase); if (args.IsAuthenticated) { args.IsAuthenticated = _BasicAuthenticationPasswordHash.PasswordMatches(args.Password); } args.IsHandled = true; } } }
/// <summary> /// Handles the authentication events from the server. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void Server_AuthenticationRequired(object sender, AuthenticationRequiredEventArgs args) { lock (_AuthenticationSyncLock) { if (!args.IsHandled) { args.IsAuthenticated = args.User != null; if (args.IsAuthenticated) { CachedUser cachedUser; var isAdministrator = false; var key = _UserManager.LoginNameIsCaseSensitive ? args.User : args.User.ToUpperInvariant(); if (_AdministratorUsers.TryGetValue(key, out cachedUser)) { isAdministrator = true; } else { _BasicAuthenticationUsers.TryGetValue(key, out cachedUser); } if (cachedUser == null) { args.IsAuthenticated = false; } else if (cachedUser.KnownGoodPassword != null && cachedUser.KnownGoodPassword == args.Password) { args.IsAuthenticated = true; } else { args.IsAuthenticated = _UserManager.PasswordMatches(cachedUser.User, args.Password); if (args.IsAuthenticated) { cachedUser.KnownGoodPassword = args.Password; } } if (args.IsAuthenticated) { args.IsAdministrator = isAdministrator; } } args.IsHandled = true; } } }
/// <summary> /// Authenticates the request from the browser. /// </summary> /// <param name="context"></param> /// <returns></returns> private bool Authenticated(IContext context) { bool result = false; switch (AuthenticationScheme) { case AuthenticationSchemes.None: case AuthenticationSchemes.Anonymous: result = true; break; case AuthenticationSchemes.Basic: bool useCache = CacheCredentials; if (useCache && context.BasicUserName != null) { string password; result = _AuthenticatedUserCache.TryGetValue(context.BasicUserName, out password) && context.BasicPassword == password; } if (!result) { var args = new AuthenticationRequiredEventArgs(context.BasicUserName, context.BasicPassword); OnAuthenticationRequired(args); result = args.IsAuthenticated; if (result) { if (useCache && args.User != null) { _AuthenticatedUserCache.Add(args.User, args.Password); } } else { context.Response.StatusCode = HttpStatusCode.Unauthorized; context.Response.AddHeader("WWW-Authenticate", String.Format(@"Basic Realm=""{0}""", Provider.ListenerRealm)); } } break; default: throw new NotImplementedException(); } return(result); }
/// <summary> /// Authenticates the request from the browser. /// </summary> /// <param name="context"></param> /// <param name="requestArgs"></param> /// <returns></returns> private bool Authenticated(IContext context, RequestReceivedEventArgs requestArgs) { bool result = false; var authenticationScheme = AuthenticationScheme; var isAdministratorPath = IsAdministratorPath(requestArgs); if (isAdministratorPath) { authenticationScheme = AuthenticationSchemes.Basic; } switch (authenticationScheme) { case AuthenticationSchemes.None: case AuthenticationSchemes.Anonymous: if (isAdministratorPath) { throw new InvalidOperationException("Anonymous access to administrator paths is not supported"); } result = true; break; case AuthenticationSchemes.Basic: bool useCache = CacheCredentials; if (useCache && context.BasicUserName != null) { CachedCredential cachedCredential; if (_AuthenticatedUserCache.TryGetValue(context.BasicUserName, out cachedCredential)) { result = context.BasicPassword == cachedCredential.Password; if (result) { result = !isAdministratorPath || cachedCredential.IsAdministrator; } } } if (!result) { var args = new AuthenticationRequiredEventArgs(context.BasicUserName, context.BasicPassword); OnAuthenticationRequired(args); result = args.IsAuthenticated && (!isAdministratorPath || args.IsAdministrator); if (result) { if (useCache && args.User != null) { var cachedCredential = new CachedCredential() { IsAdministrator = args.IsAdministrator, Password = context.BasicPassword, }; _AuthenticatedUserCache.Add(context.BasicUserName, cachedCredential); } } else { var failedLogin = _FailedLoginAttempts.GetAndRefreshOrCreate(context.Request.RemoteEndPoint.Address, (unused) => new FailedLogin()); var sameCredentials = context.BasicUserName == failedLogin.User && context.BasicPassword == failedLogin.Password; failedLogin.User = context.BasicUserName; failedLogin.Password = context.BasicPassword; if (!sameCredentials) { if (failedLogin.Attempts < int.MaxValue) { ++failedLogin.Attempts; } if (failedLogin.Attempts > 2) { var pauseMilliseconds = (Math.Min(failedLogin.Attempts, 14) - 2) * 5000; Thread.Sleep(pauseMilliseconds); } } context.Response.StatusCode = HttpStatusCode.Unauthorized; context.Response.AddHeader("WWW-Authenticate", String.Format(@"Basic Realm=""{0}""", Provider.ListenerRealm)); } } if (result) { requestArgs.UserName = context.BasicUserName; } break; default: throw new NotImplementedException(); } return(result); }
/// <summary> /// Raises <see cref="OnAuthenticationRequired"/>. /// </summary> /// <param name="args"></param> private void OnAuthenticationRequired(AuthenticationRequiredEventArgs args) { EventHelper.RaiseQuickly(AuthenticationRequired, this, args); }