Beispiel #1
0
        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
        }