private bool IsAccessible(HubDescriptor hubDescriptor, IRequest request) { try { #region Connection validity check // Find request principle. var principle = request.User; // Request has been authenticated before. if (principle != null && principle.Identity != null && principle.Identity.IsAuthenticated) { return(true); } #endregion #region Authentication cookie analyze // Find authentication cookie from the request. var formAuthenticationCookie = request.Cookies[FormsAuthentication.FormsCookieName]; // Invalid form authentication cookie. if (formAuthenticationCookie == null) { if (IsAnonymousAllowed(hubDescriptor)) { return(true); } Logger.Error("Invalid authentication cookie"); return(false); } //Cookie value is invalid if (string.IsNullOrWhiteSpace(formAuthenticationCookie.Value)) { if (IsAnonymousAllowed(hubDescriptor)) { return(true); } Logger.Error("Invalid authentication cookie value"); return(false); } #endregion #region Form authentication ticket // Decrypt the authentication cookie value to authentication ticket instance. var formAuthenticationTicket = FormsAuthentication.Decrypt(formAuthenticationCookie.Value); // Ticket is invalid. if (formAuthenticationTicket == null) { if (IsAnonymousAllowed(hubDescriptor)) { return(true); } Logger.Error("Invalid authentication cookie ticket"); return(false); } // User data is invalid. if (string.IsNullOrWhiteSpace(formAuthenticationTicket.UserData)) { if (IsAnonymousAllowed(hubDescriptor)) { return(true); } Logger.Error("Invalid authentication cookie user data"); return(false); } #endregion #region IP Address validation // Find the user data in the ticket. var loginViewModel = JsonConvert.DeserializeObject <LoginItem>(formAuthenticationTicket.UserData); // User data is invalid. if (loginViewModel == null) { if (IsAnonymousAllowed(hubDescriptor)) { return(true); } Logger.Error("Authentication ticket information is invalid."); return(false); } // Find IP Address of request. var requestIpAddress = _loginDomain.FindRequestIpAddress(request.GetHttpContext()); // Cookie doesn't come from the same origin. if (string.IsNullOrEmpty(requestIpAddress) || !requestIpAddress.Equals(loginViewModel.IpAddress)) { if (IsAnonymousAllowed(hubDescriptor)) { return(true); } Logger.Error(string.Format("Cookie doesn't come from the same origin as the request (Source: {0} - Target: {1})", loginViewModel.IpAddress, loginViewModel.Password)); return(false); } #endregion #region Passsword // No password is included in cookie. if (string.IsNullOrEmpty(loginViewModel.Password)) { if (IsAnonymousAllowed(hubDescriptor)) { return(true); } Logger.Error("No password is included in the cookie."); return(false); } // Find password setting. var passwordSetting = _loginDomain.FindPasswordSetting(loginViewModel.Password); if (passwordSetting == null) { if (IsAnonymousAllowed(hubDescriptor)) { return(true); } Logger.Error(string.Format("Password {0}", loginViewModel.Password)); return(false); } #endregion #region Terminal // Analyze client ip address. var ips = LoginDomain.AnalyzeIpAddress(requestIpAddress); // Find terminal by searching ip address. var terminal = _loginDomain.FindTerminalFromIpAddress(ips); // No terminal has been found in the request. if (terminal == null) { // Unauthenticated request is allowed to access function. if (IsAnonymousAllowed(hubDescriptor)) { return(true); } Logger.Error(string.Format("No terminal has been found with IP : {0}", requestIpAddress)); return(false); } // Accessible terminals are defined. // Terminal cannot access to the sensitive hub. if (_accessibleTerminals != null && !_accessibleTerminals.Any(x => x.Equals(terminal.F06_TerminalNo))) { // Unauthenticated request is allowed to access function. if (IsAnonymousAllowed(hubDescriptor)) { return(true); } Logger.Error(string.Format("No terminal has been found with IP : {0}", requestIpAddress)); return(false); } #endregion var claimIdentity = new ClaimsIdentity(null, _loginDomain.AuthenticationClaimName); claimIdentity.AddClaim(new Claim(ClientIdentities.TerminalNo, terminal.F06_TerminalNo)); claimIdentity.AddClaim(new Claim(ClientIdentities.IpAddress, requestIpAddress)); var httpContext = request.GetHttpContext(); httpContext.User = new ClaimsPrincipal(claimIdentity); return(true); } catch (Exception exception) { Logger.Error(exception.Message, exception); return(false); } }
/// <summary> /// This function is for parsing cookie, querying database and decide whether user can access the function or not. /// </summary> /// <param name="authorizationContext"></param> public void OnAuthorization(AuthorizationContext authorizationContext) { #if !UNAUTHORIZED_DEBUG using (var context = new KCSGDbContext()) using (var unitOfWork = new UnitOfWork(context)) { try { var loginDomain = new LoginDomain(unitOfWork); // Initiate authentication result. var authenticationResult = new AuthenticationResult(); #region Authentication cookie & ticket validation var formAuthenticationCookie = authorizationContext.RequestContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName]; if (formAuthenticationCookie == null) { if (IsAnonymousAllowed(authorizationContext)) { return; } FormsAuthentication.SignOut(); authorizationContext.Result = new HttpUnauthorizedResult(); Log.Error("Authentication cookie is invalid."); return; } //Cookie value is invalid if (string.IsNullOrWhiteSpace(formAuthenticationCookie.Value)) { if (IsAnonymousAllowed(authorizationContext)) { return; } // Sign the user out to clear the cookie. FormsAuthentication.SignOut(); // Treat the request as unauthorized. authorizationContext.Result = new HttpUnauthorizedResult(); Log.Error("Authentication cookie value is invalid."); return; } // Decrypt the authentication cookie value to authentication ticket instance. var formAuthenticationTicket = FormsAuthentication.Decrypt(formAuthenticationCookie.Value); // Ticket is invalid. if (formAuthenticationTicket == null) { if (IsAnonymousAllowed(authorizationContext)) { return; } // Sign the user out to clear the cookie. FormsAuthentication.SignOut(); // Treat the request as unauthorized. authorizationContext.Result = new HttpUnauthorizedResult(); Log.Error("Authentication ticket is not valid."); return; } // User data is invalid. if (string.IsNullOrWhiteSpace(formAuthenticationTicket.UserData)) { if (IsAnonymousAllowed(authorizationContext)) { return; } // Sign the user out to clear the cookie. FormsAuthentication.SignOut(); // Treat the request as unauthorized. authorizationContext.Result = new HttpUnauthorizedResult(); Log.Error("Authentication ticket's user data is invalid."); return; } #endregion #region IP Address validation // Find the user data in the ticket. var loginViewModel = JsonConvert.DeserializeObject <LoginItem>(formAuthenticationTicket.UserData); // User data is invalid. if (loginViewModel == null) { if (IsAnonymousAllowed(authorizationContext)) { return; } // Sign the user out to clear the cookie. FormsAuthentication.SignOut(); // Treat the request as unauthorized. authorizationContext.Result = new HttpUnauthorizedResult(); Log.Error("Authentication ticket information is invalid."); return; } // Find IP Address of request. var requestIpAddress = loginDomain.FindRequestIpAddress(authorizationContext.HttpContext); // Cookie doesn't come from the same origin. if (string.IsNullOrEmpty(requestIpAddress) || !requestIpAddress.Equals(loginViewModel.IpAddress)) { if (IsAnonymousAllowed(authorizationContext)) { return; } // Sign the user out to clear the cookie. FormsAuthentication.SignOut(); // Treat the request as unauthorized. authorizationContext.Result = new HttpUnauthorizedResult(); Log.Error(string.Format("Cookie doesn't come from the same origin as the request (Source: {0} - Target: {1})", loginViewModel.IpAddress, loginViewModel.Password)); return; } #endregion #region Passsword // No password is included in cookie. if (string.IsNullOrEmpty(loginViewModel.Password)) { if (IsAnonymousAllowed(authorizationContext)) { return; } // Sign the user out to clear the cookie. FormsAuthentication.SignOut(); // Treat the request as unauthorized. authorizationContext.Result = new HttpUnauthorizedResult(); Log.Error("No password is included in the cookie."); return; } // Find password setting. var passwordSetting = loginDomain.FindPasswordSetting(loginViewModel.Password); if (passwordSetting == null) { if (IsAnonymousAllowed(authorizationContext)) { return; } // Sign the user out to clear the cookie. FormsAuthentication.SignOut(); // Treat the request as unauthorized. authorizationContext.Result = new HttpUnauthorizedResult(); Log.Error(string.Format("Password {0}", loginViewModel.Password)); return; } // Find the password level. authenticationResult.PasswordLevel = passwordSetting.F16_PswdLevel; #endregion #region Terminal // Analyze client ip address. var ips = loginDomain.AnalyzeIpAddress(requestIpAddress); // Find terminal by searching ip address. var terminal = loginDomain.FindTerminalFromIpAddress(ips); // No terminal has been found in the request. if (terminal == null) { // Unauthenticated request is allowed to access function. if (IsAnonymousAllowed(authorizationContext)) { return; } // Sign the user out to clear the cookie. FormsAuthentication.SignOut(); // Treat the request as unauthorized. authorizationContext.Result = new HttpUnauthorizedResult(); Log.Error(string.Format("No terminal has been found with IP : {0}", requestIpAddress)); return; } // Update authentication result. authenticationResult.TerminalNo = terminal.F06_TerminalNo; #endregion #region Cookie authentication // Find the current system time on the server. var systemTime = DateTime.Now; // Login is successful, save the information in the cookie for future use. formAuthenticationTicket = new FormsAuthenticationTicket(1, loginDomain.AuthenticationTicketName, systemTime, systemTime.AddMinutes(30), true, JsonConvert.SerializeObject(loginViewModel)); // Initialize cookie contain the authorization ticket. var httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(formAuthenticationTicket)); authorizationContext.HttpContext.Response.Cookies.Add(httpCookie); // Set credential for the HttpContext. var claimIdentity = new ClaimsIdentity(null, loginDomain.AuthenticationClaimName); claimIdentity.AddClaim(new Claim(ClientIdentities.TerminalNo, authenticationResult.TerminalNo)); claimIdentity.AddClaim(new Claim(ClientIdentities.IpAddress, requestIpAddress)); claimIdentity.AddClaim(new Claim(ClientIdentities.PasswordLevel, authenticationResult.PasswordLevel)); #endregion #region Accessible screens // Find list of accessible screens by using terminal functions & functions management. var availableScreens = loginDomain.FindAccessibleScreens(authenticationResult.TerminalNo, authenticationResult.PasswordLevel); // No screen has been found. if (availableScreens == null || availableScreens.Count < 1) { // Unauthenticated request is allowed to access function. if (IsAnonymousAllowed(authorizationContext)) { return; } // Treat the request as forbidden. authorizationContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden); Log.Error(string.Format("No available screen has been found for terminal {0}", authenticationResult.TerminalNo)); return; } // Update available screens list to the terminal. authenticationResult.AccessibleScreens = availableScreens; // Identity update. claimIdentity.AddClaim(new Claim(ClientIdentities.AccessibleScreens, string.Join(",", authenticationResult.AccessibleScreens))); if (_screens != null) { claimIdentity.AddClaim(new Claim(ClientIdentities.AccessingScreen, string.Join(",", _screens))); } var claimsPrincipal = new ClaimsPrincipal(claimIdentity); authorizationContext.HttpContext.User = claimsPrincipal; // At least one screen has been specified to the target controller/action. if (_screens != null && _screens.Length > 0) { // Check whether terminal can access to screen or not. var isScreenAccessible = availableScreens.Any(x => _screens.Any(y => x.Equals(y))); if (!isScreenAccessible) { // Treat the request as forbidden. authorizationContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden); Log.Error(string.Format("Terminal {0} cannot access to screens : {1}", authenticationResult.TerminalNo, string.Join(",", _screens))); } } // Access of terminal to screen is locked. if (IsAccessLocked(terminal.F06_TerminalNo)) { var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext); authorizationContext.Result = new RedirectResult(urlHelper.Action("Index", "Home", new { Area = "", @isLockScreen = true })); } #endregion } catch (UnauthorizedAccessException) { authorizationContext.Result = new HttpStatusCodeResult(HttpStatusCode.Unauthorized); } } #elif UNAUTHORIZED_DEBUG #endif }