/// <summary>设置当前用户</summary>
        /// <param name="user"></param>
        /// <param name="context"></param>
        public override void SetCurrent(IManageUser user, IServiceProvider context = null)
        {
            var ctx = (ModelExtension.GetService <IHttpContextAccessor>(context) ?? Context)
                      ?.HttpContext;

            if (ctx == null)
            {
                return;
            }

            ctx.Items["CurrentUser"] = user;

            var session = ctx.Items["Session"] as IDictionary <String, Object>;

            if (session == null)
            {
                return;
            }

            var key = SessionKey;

            // 特殊处理注销
            if (user == null)
            {
                session.Remove(key);
                session.Remove("userId");
            }
            else
            {
                session[key]      = user;
                session["userId"] = user.ID;
            }
        }
        ///// <summary>当前管理提供者</summary>
        //public new static IManageProvider Provider => ObjectContainer.Current.ResolveInstance<IManageProvider>();

        #region IManageProvider 接口
        /// <summary>获取当前用户</summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override IManageUser GetCurrent(IServiceProvider context = null)
        {
            var ctx = (ModelExtension.GetService <IHttpContextAccessor>(context) ?? Context)?.HttpContext;

            if (ctx == null)
            {
                return(null);
            }

            try
            {
                if (ctx.Items["CurrentUser"] is IManageUser user)
                {
                    return(user);
                }

                var session = ctx.Items["Session"] as IDictionary <String, Object>;

                user = session?[SessionKey] as IManageUser;
                ctx.Items["CurrentUser"] = user;

                return(user);
            }
            catch (InvalidOperationException ex)
            {
                // 这里捕获一下,防止初始化应用中session还没初始化好报的异常
                // 这里有个问题就是这里的ctx会有两个不同的值
                XTrace.WriteException(ex);
                return(null);
            }
        }
        /// <summary>设置当前用户</summary>
        /// <param name="provider">提供者</param>
        /// <param name="context">Http上下文,兼容NetCore</param>
        public static void SetPrincipal(this IManageProvider provider, IServiceProvider context = null)
        {
            var ctx = ModelExtension.GetService <IHttpContextAccessor>(context)?.HttpContext;

            if (ctx == null)
            {
                return;
            }

            var user = provider.GetCurrent(context);

            if (user == null)
            {
                return;
            }

            if (user is not IIdentity id || ctx.User?.Identity == id)
            {
                return;
            }

            // 角色列表
            var roles = new List <String>();

            if (user is IUser user2)
            {
                roles.AddRange(user2.Roles.Select(e => e + ""));
            }

            var up = new GenericPrincipal(id, roles.ToArray());

            ctx.User = up;
            Thread.CurrentPrincipal = up;
        }
        /// <summary>
        /// 使用管理提供者
        /// </summary>
        /// <param name="app"></param>
        public static void UseManagerProvider(this IApplicationBuilder app)
        {
            XTrace.WriteLine("初始化ManageProvider");

            var provider = app.ApplicationServices;

            ManageProvider.Provider = ModelExtension.GetService <IManageProvider>(provider);
            ManageProvider2.Context = ModelExtension.GetService <IHttpContextAccessor>(provider);

            // 初始化数据库
            _ = Role.Meta.Count;
        }
        /// <summary>使用魔方UI</summary>
        /// <param name="app"></param>
        /// <param name="env"></param>
        /// <returns></returns>
        public static IApplicationBuilder UseMetronic(this IApplicationBuilder app, IWebHostEnvironment env)
        {
            // 独立静态文件设置,魔方自己的静态资源内嵌在程序集里面
            var options = new StaticFileOptions();

            {
                var embeddedProvider = new CubeEmbeddedFileProvider(Assembly.GetExecutingAssembly(), "NewLife.Cube.Metronic.wwwroot");
                options.FileProvider = embeddedProvider;
            }
            app.UseStaticFiles(options);

            var ui = ModelExtension.GetService <UIService>(app.ApplicationServices);

            if (ui != null)
            {
                ui.AddTheme("Metronic3");
                ui.AddSkin("Metronic3");
            }

            return(app);
        }
Beispiel #6
0
        /// <summary>登录成功</summary>
        /// <param name="client">OAuth客户端</param>
        /// <param name="context">服务提供者。可用于获取HttpContext成员</param>
        /// <param name="uc">用户链接</param>
        /// <param name="forceBind">强行绑定,把第三方账号强行绑定到当前已登录账号</param>
        /// <returns></returns>
        public virtual String OnLogin(OAuthClient client, IServiceProvider context, UserConnect uc, Boolean forceBind)
        {
            //// 强行绑定,把第三方账号强行绑定到当前已登录账号
            //var forceBind = false;
#if __CORE__
            var httpContext = ModelExtension.GetService <IHttpContextAccessor>(context).HttpContext;
            var req         = httpContext.Request;
            var ip          = httpContext.GetUserHost();
#else
            var req         = context.GetService <HttpRequest>();
            var httpContext = req.RequestContext.HttpContext;
            var ip          = httpContext.GetUserHost();
#endif

            // 可能因为初始化顺序的问题,导致前面没能给Provider赋值
            var prv = Provider;
            if (prv == null)
            {
                prv = Provider = ManageProvider.Provider;
            }

            // 检查绑定,新用户的uc.UserID为0
            var user = prv.FindByID(uc.UserID);
            if (forceBind || user == null || !uc.Enable)
            {
                user = OnBind(uc, client);
            }

            try
            {
                uc.UpdateTime = DateTime.Now;
                uc.Save();
            }
            catch (Exception ex)
            {
                //为了防止某些特殊数据导致的无法正常登录,把所有异常记录到日志当中。忽略错误
                XTrace.WriteException(ex);
            }

            // 如果应用不支持自动注册,此时将得不到用户,跳回去登录页面
            if (user == null)
            {
                return(null);
            }

            // 填充昵称等数据
            Fill(client, user);

            if (user is IAuthUser user3)
            {
                user3.Logins++;
                user3.LastLogin   = DateTime.Now;
                user3.LastLoginIP = ip;
                //user3.Save();
                //(user3 as IEntity).Update();
            }
            if (user is IEntity entity)
            {
                entity.Update();
            }

            // 写日志
            var log = LogProvider.Provider;
            log?.WriteLog(typeof(User), "SSO登录", true, $"[{user}]从[{client.Name}]的[{client.UserName ?? client.NickName}]登录", user.ID, user + "");

            if (!user.Enable)
            {
                throw new InvalidOperationException($"用户[{user}]已禁用!");
            }

            // 登录成功,保存当前用户
            if (prv is ManageProvider2 prv2)
            {
                user = prv2.CheckAgent(user);
            }
            prv.Current = user;

            // 单点登录不要保存Cookie,让它在Session过期时请求认证中心
            //prv.SaveCookie(user);
            var set = Setting.Current;
            if (set.SessionTimeout > 0)
            {
                var expire = TimeSpan.FromSeconds(set.SessionTimeout);
#if __CORE__
                prv.SaveCookie(user, expire, httpContext);
#else
                prv.SaveCookie(user, expire, httpContext.ApplicationInstance.Context);
#endif
            }

            return(SuccessUrl);
        }