SSOController.cs 5.21 KB
// ***********************************************************************
// <summary>
// 基础控制器
// 继承该控制器可以防止未登录查看
// 继承该控制器后,如果想访问控制器中存在,但模块配置里面没有的Action(如:Home/Git),请使用AnonymousAttribute
// </summary>
// ***********************************************************************

using System;
using System.Linq;
using Hh.Mes.Common.config;
using Hh.Mes.Common.log;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using WebRepository;

namespace WebApp
{
    public class SSOController : Controller
    {
        public const string token = "Token";
        public const string referer = "Referer";
        public const string origin = "Origin";
        public AuthStrategyContext authStrategyContext = null;
        protected LoginInfo _loginInfo;
        protected IAuth _authUtil;
        private HttpRequest httpContext { get; set; }

        public SSOController(IAuth authUtil)
        {
            _authUtil = authUtil;
            authStrategyContext = _authUtil.GetCurrentUser();
            if (authStrategyContext != null)
            {
                _loginInfo = new LoginInfo
                {
                    Id = authStrategyContext.User.Id,
                    Account = authStrategyContext.User.Account,
                    Name = authStrategyContext.User.Name,
                };
            }
            else
            {
                LoginResult(token);
            }
        }

        /// <summary>
        ///  会话丢失,跳转到登录页面
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            ActionBefore(filterContext);
        }

        public virtual ContentResult LoginResult(string falg)
        {
            var msg = "";
            switch (falg)
            {
                case token:
                    msg = "Token登入失效,点击确定后将返回登入页面";
                    break;
                case referer:
                case origin:
                    msg = "安全检验不通过!";
                    break;
            }

            var js = $"alert('{msg}');parent.window.location.href = '/Login/Index'; ";
            var Content = new ContentResult
            {
                Content = $"<script type='text/javascript'>{js}</script>",
                ContentType = "text/html;charset=utf-8",
                StatusCode = 200
            };
            return Content;
        }


        public void ActionBefore(ActionExecutingContext filterContext)
        {
            httpContext = filterContext.HttpContext.Request;
            var temp = ConfigRead.GetInstance.GetAppsetConnection().ServerIPList;
            var ServersIPList = temp.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
            //验证Referer
            string userReferer = filterContext.HttpContext.Request.Headers[referer];
            if (string.IsNullOrEmpty(userReferer))
            {
                filterContext.Result = LoginResult(referer);
                return;
            }
            if (!ServersIPList.Exists(t => userReferer.StartsWith("https://" + t)))
            {
                filterContext.Result = LoginResult(referer); ;
                return;
            }

            //验证Origin
            string userOrigin = filterContext.HttpContext.Request.Headers[origin];
            if (string.IsNullOrEmpty(userOrigin))
            {
                if (filterContext.HttpContext.Request.Method != "GET" && filterContext.HttpContext.Request.Method != "HEAD")
                {
                    filterContext.Result = LoginResult(origin); ;
                    return;
                }
            }
            else
            {
                if (!ServersIPList.Exists(t => userOrigin.StartsWith("https://" + t)))
                {
                    filterContext.Result = LoginResult(origin); ;
                    return;
                }
            }
            if (AopAllowed())
            {
                base.OnActionExecuting(filterContext);
                return;
            }
            //验证Cookies
            string userToken = filterContext.HttpContext.Request.Cookies[token];
            if (string.IsNullOrEmpty(userToken) || _loginInfo == null)
            {
                filterContext.Result = LoginResult(token);
                return;
            }

            if (_authUtil.CheckLogin(userToken) == false)
            {
                filterContext.Result = LoginResult(token);
                return;
            }
            base.OnActionExecuting(filterContext);
        }


        /// <summary>
        /// 当前url 是否匹配 忽略拦截的 配置路径
        /// </summary>
        /// <returns></returns>
        private bool AopAllowed()
        {
            var allowedUrl = ConfigRead.GetInstance.GetAppsetConnection().allowed;
            if (allowedUrl == null || allowedUrl.Length == 0) return false;

            var url = httpContext.Path.Value;
            return allowedUrl.Any(item => url.IndexOf(item, StringComparison.Ordinal) > -1);
        }
    }
}