Exemplo n.º 1
0
        /// <summary>
        /// 使用指定程序集初始化权限节点
        /// </summary>
        /// <param name="assembly"></param>
        /// <param name="connectionString"></param>
        /// <param name="appId"></param>
        /// <param name="preAccessEndPointKey"></param>
        public static void InitAccessEndPointData(Assembly assembly, string connectionString, string appId, string preAccessEndPointKey)
        {
            using var npgsqlDapperHelper = NpgsqlDapperHelper.Helper(connectionString);

            //加载授权节点
            IEnumerable <AuthEndPointAttribute> authEndPointParms = new AuthEndPointAttribute[0];
            string assemblyName = assembly.FullName.Split()[0]?.Trim(',') + ".Controllers";
            var    types        = assembly.GetTypes().Where(x => !x.IsNestedPrivate && x.FullName.StartsWith(assemblyName)).ToList();

            foreach (var item in types)
            {
                var accessParm = AuthServiceCollectionExtensions.GetClassAccessParm_AuthEndPointAttribute(item);
                authEndPointParms = authEndPointParms.Union(accessParm);
                foreach (AuthEndPointAttribute parmItem in accessParm)
                {
                    if (parmItem == null)
                    {
                        continue;
                    }

                    if (string.IsNullOrEmpty(parmItem.AuthEndPoint))
                    {
                        parmItem.AuthEndPoint = $"{preAccessEndPointKey}:{parmItem.ControllerName}.{parmItem.ActionName}";
                    }

                    Console.WriteLine($"加载成功 -> {parmItem.AuthEndPoint}");
                }
            }

            foreach (var item in authEndPointParms)
            {
                var https      = item.Routes.Select(x => x.HttpMethods).SelectMany((x, y) => x).Select(x => x.ToUpper());
                int httpMethod = 0;
                foreach (var method in https)
                {
                    HttpMethod.HttpMethodMaps.TryGetValue(method, out int val);
                    httpMethod |= val;
                }

                npgsqlDapperHelper.Execute(@$ "INSERT INTO " "Sys_Access" " (" "Id" "," "AccessCode" "," "AppId" "," "RequestMethod" ") VALUES('{Guid.NewGuid().ToString(" N ")}','{item.AuthEndPoint}','{(appId == null ? string.Empty : appId)}','{httpMethod}')");
            }
        }
        /// <summary>
        /// 配置授权服务运行状态
        /// </summary>
        /// <param name="services"></param>
        /// <param name="setupAction"></param>
        public static void ConfigureAuth(this IServiceCollection services, Action <AuthOptions> setupAction)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (setupAction == null)
            {
                throw new ArgumentNullException(nameof(setupAction));
            }

            AuthOptions authOptions = new AuthOptions();

            setupAction(authOptions);
            services.AddSingleton(x => authOptions);

            services.TryAddSingleton <IAuthService, AuthenticationService>();

            ServiceProvider sp          = services.BuildServiceProvider();
            IAuthService    authService = sp.GetService <IAuthService>();

            Assembly assembly = null;

            if (string.IsNullOrEmpty(authOptions?.WatchAssemblyPath))
            {
                assembly = Assembly.GetEntryAssembly();
            }
            else
            {
                assembly = Assembly.LoadFile(authOptions.WatchAssemblyPath);
            }

            #region MyRegion

            ////加载授权节点
            //IEnumerable<AuthEndPointParm> authEndPointParms = new AuthEndPointParm[0];
            //string assemblyName = assembly.FullName.Split()[0]?.Trim(',') + ".Controllers";
            //var types = assembly.GetTypes().Where(x => !x.IsNestedPrivate && x.FullName.StartsWith(assemblyName)).ToList();
            //foreach (var item in types)
            //{
            //    var accessParm = authService.GetClassAccessParm(item);
            //    authEndPointParms = authEndPointParms.Union(accessParm);
            //    foreach (AuthEndPointParm parmItem in accessParm)
            //    {
            //        foreach (var attItem in parmItem.AuthEndPointAttributes)
            //        {
            //            if (attItem == null)
            //            {
            //                continue;
            //            }

            //            if (string.IsNullOrEmpty(attItem.AuthEndPoint))
            //            {
            //                attItem.AuthEndPoint = $"{parmItem.ControllerName}.{parmItem.ActionName}";
            //            }

            //            authService.RegisterAccessCode(attItem.AuthEndPoint, attItem.IsAllow);

            //            Console.WriteLine($"加载成功 -> {attItem.AuthEndPoint} 允许访问");
            //        }

            //    }

            //}

            //authOptions.WatchAuthEndPoint = authEndPointParms.ToArray();
            #endregion

            //正则匹配有鉴权攻击风险!!!

            //加载授权节点
            IEnumerable <AuthEndPointAttribute> authEndPointParms = new AuthEndPointAttribute[0];
            string assemblyName = assembly.FullName.Split()[0]?.Trim(',') + ".Controllers";
            var    types        = assembly.GetTypes().Where(x => !x.IsNestedPrivate && x.FullName.StartsWith(assemblyName)).ToList();
            foreach (var item in types)
            {
                AuthEndPointAttribute[] accessParm = AuthServiceCollectionExtensions.GetClassAccessParm_AuthEndPointAttribute(item);
                authEndPointParms = authEndPointParms.Union(accessParm);
                foreach (AuthEndPointAttribute parmItem in accessParm)
                {
                    if (parmItem == null)
                    {
                        continue;
                    }

                    if (string.IsNullOrEmpty(parmItem.AuthEndPoint))
                    {
                        parmItem.AuthEndPoint = $"{authOptions.PreAccessEndPointKey}:{parmItem.ControllerName}.{parmItem.ActionName}";
                    }

                    authService.RegisterAccessCode(parmItem.AuthEndPoint, parmItem.IsAllow);

                    Console.WriteLine($"加载成功 -> {parmItem.AuthEndPoint} 允许访问");
                }

                AuthEnableRegexAttribute[] accessRegexParm = AuthServiceCollectionExtensions.GetClassAccessParm_AuthEnableRegexAttribute(item);
                foreach (AuthEnableRegexAttribute parmItem in accessRegexParm)
                {
                    if (parmItem == null)
                    {
                        continue;
                    }

                    parmItem.AuthEndPoint = $"{authOptions.PreAccessEndPointKey}:Regex⊇{parmItem.AuthEndPoint}";
                    authService.RegisterAccessCode(parmItem.AuthEndPoint, parmItem.IsAllow);

                    Console.WriteLine($"加载成功 -> {parmItem.AuthEndPoint} 允许访问");
                }
            }


            authOptions.WatchAuthEndPoint = authEndPointParms.ToArray();


            //获取处理后的缓存并覆盖
            var memoryCache = sp.GetService <IMemoryCache>();

            var existService = services.FirstOrDefault(x => x.ServiceType == typeof(IMemoryCache));
            services.Remove(existService);

            services.TryAddSingleton <IMemoryCache>(x => memoryCache);
        }