Example #1
0
        private async Task <LoginViewModel> BuildLoginViewModelAsync(string returnUrl)
        {
            var context = await InteractionService.GetAuthorizationContextAsync(returnUrl);

            if (context?.IdP != null)
            {
                var local = context.IdP == IdentityServerConstants.LocalIdentityProvider;

                var vm = new LoginViewModel {
                    EnableLocalLogin = local,
                    ReturnUrl        = returnUrl,
                    UserName         = context?.LoginHint,
                };

                if (!local)
                {
                    vm.ExternalProviders = new[] { new ExternalProvider {
                                                       AuthenticationScheme = context.IdP
                                                   } };
                }

                return(vm);
            }

            var schemes = await AuthenticationSchemeProvider.GetAllSchemesAsync();

            var providers = schemes
                            .Where(x => x.DisplayName != null ||
                                   (x.Name.Equals(AccountOptions.WindowsAuthenticationSchemeName, StringComparison.OrdinalIgnoreCase))
                                   )
                            .Select(x => new ExternalProvider {
                DisplayName          = x.DisplayName,
                AuthenticationScheme = x.Name
            }).ToList();

            var allowLocal = true;

            if (context?.ClientId != null)
            {
                //var client = await _clientStore.FindEnabledClientByIdAsync( context.ClientId );
                //if( client != null ) {
                //    allowLocal = client.EnableLocalLogin;

                //    if( client.IdentityProviderRestrictions != null && client.IdentityProviderRestrictions.Any() ) {
                //        providers = providers.Where( provider => client.IdentityProviderRestrictions.Contains( provider.AuthenticationScheme ) ).ToList();
                //    }
                //}
            }

            return(new LoginViewModel {
                AllowRemember = AccountOptions.AllowRemember,
                EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,
                ReturnUrl = returnUrl,
                UserName = context?.LoginHint,
                ExternalProviders = providers.ToArray()
            });
        }
        private SignInManager <User> GetSignInManager(UserManager <User> userManager)
        {
            IdentityOptions identityOptions = new IdentityOptions
            {
                SignIn = new SignInOptions
                {
                    RequireConfirmedEmail       = false,
                    RequireConfirmedPhoneNumber = false
                },
                User = new UserOptions
                {
                    RequireUniqueEmail = true
                },
                Lockout = new LockoutOptions
                {
                    AllowedForNewUsers = true
                }
            };

            Mock <IOptions <IdentityOptions> > mockIdentityOptions = new Mock <IOptions <IdentityOptions> >();

            mockIdentityOptions.Setup(a => a.Value).Returns(identityOptions);
            Mock <IHttpContextAccessor> mockHttpContext = new Mock <IHttpContextAccessor>();

            mockHttpContext
            .Setup(a => a.HttpContext)
            .Returns(new DefaultHttpContext());

            Mock <IUserClaimsPrincipalFactory <User> > mockUserClaimsPrincipalFactory = new Mock <IUserClaimsPrincipalFactory <User> >();

            mockUserClaimsPrincipalFactory
            .Setup(a => a.CreateAsync(It.IsAny <User>()))
            .Returns(Task.FromResult(new ClaimsPrincipal()));

            Mock <ILogger <SignInManager <User> > > mockLogger = new Mock <ILogger <SignInManager <User> > >();
            AuthenticationOptions authenticationOptions        = new AuthenticationOptions
            {
            };
            Mock <IOptions <AuthenticationOptions> > mockAuthOptions = new Mock <IOptions <AuthenticationOptions> >();

            mockAuthOptions.Setup(a => a.Value).Returns(authenticationOptions);
            AuthenticationSchemeProvider     authenticationSchemeProvider = new AuthenticationSchemeProvider(mockAuthOptions.Object);
            Mock <IUserConfirmation <User> > mockUserConfirmation         = new Mock <IUserConfirmation <User> >();

            mockUserConfirmation.Setup(a => a.IsConfirmedAsync(It.IsAny <UserManager <User> >(), It.IsAny <User>())).Returns(Task.FromResult(true));
            FakeSignInManager signInManager = new FakeSignInManager(
                userManager,
                mockHttpContext.Object,
                mockUserClaimsPrincipalFactory.Object,
                mockIdentityOptions.Object,
                mockLogger.Object,
                authenticationSchemeProvider,
                mockUserConfirmation.Object
                );

            return(signInManager);
        }
        protected void Check(JObject jObj, AuthenticationSchemeProvider authSchemeProvider)
        {
            var optionsType       = Type.GetType(authSchemeProvider.OptionsFullQualifiedName);
            var properties        = optionsType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(s => s.Name);
            var jObjProperties    = jObj.Properties().Select(p => p.Name);
            var unknownProperties = jObjProperties.Where(p => !properties.Contains(p));

            if (unknownProperties.Any())
            {
                var message = string.Format(ErrorMessages.UNKNOWN_AUTH_SCHEME_PROVIDER_PROPERTIES, string.Join(",", unknownProperties));
                _logger.LogError(message);
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, message);
            }
        }
Example #4
0
        public static JObject ToDto(this AuthenticationSchemeProvider authenticationSchemeProvider)
        {
            var result = new JObject();

            result.Add(AuthenticationSchemeProviderParameters.CreateDateTime, authenticationSchemeProvider.CreateDateTime);
            result.Add(AuthenticationSchemeProviderParameters.DisplayName, authenticationSchemeProvider.DisplayName);
            result.Add(AuthenticationSchemeProviderParameters.HandlerFullQualifiedName, authenticationSchemeProvider.HandlerFullQualifiedName);
            result.Add(AuthenticationSchemeProviderParameters.Id, authenticationSchemeProvider.Id);
            result.Add(AuthenticationSchemeProviderParameters.IsEnabled, authenticationSchemeProvider.IsEnabled);
            result.Add(AuthenticationSchemeProviderParameters.JsonConverter, authenticationSchemeProvider.JsonConverter);
            result.Add(AuthenticationSchemeProviderParameters.Name, authenticationSchemeProvider.Name);
            result.Add(AuthenticationSchemeProviderParameters.Options, authenticationSchemeProvider.JsonOptions);
            result.Add(AuthenticationSchemeProviderParameters.UpdateDateTime, authenticationSchemeProvider.UpdateDateTime);
            return(result);
        }
Example #5
0
        public async Task <string> GetAuthenticationScheme()
        {
            var schemeHandlers = await AuthenticationSchemeProvider.GetAllSchemesAsync();

            foreach (var scheme in schemeHandlers)
            {
                var authResult = await HttpContext.AuthenticateAsync(scheme.Name);

                if (authResult.Succeeded)
                {
                    return(scheme.Name);
                }
            }
            return(null);
        }
Example #6
0
        public async Task <IActionResult> ExternalLogin([FromQuery] string provider)
        {
            // Note: the "provider" parameter corresponds to the external
            // authentication provider choosen by the user agent.
            if (string.IsNullOrWhiteSpace(provider))
            {
                return(BadRequest());
            }

            if (await AuthenticationSchemeProvider.GetSchemeAsync(provider) == null)
            {
                return(BadRequest());
            }

            // Instruct the middleware corresponding to the requested external identity
            // provider to redirect the user agent to its own authorization endpoint.
            // Note: the authenticationScheme parameter must match the value configured in Startup.cs
            string redirectUri = Url.Action(nameof(ExternalLoginCallback), "Account");

            return(Challenge(new AuthenticationProperties {
                RedirectUri = redirectUri
            }, provider));
        }
Example #7
0
        public async Task When_Update_Request_Doesnt_Contain_Valid_Properties_Then_Exception_Is_Thrown()
        {
            // ARRANGE
            var repository = new Mock <IAuthenticationSchemeProviderRepository>();
            var logger     = new Mock <ILogger <UpdateAuthSchemeProviderOptionsHandler> >();
            var handler    = new UpdateAuthSchemeProviderOptionsHandler(repository.Object, logger.Object);
            var authenticationSchemeProvider = new AuthenticationSchemeProvider
            {
                OptionsFullQualifiedName = typeof(OptionsLite).AssemblyQualifiedName
            };

            repository.Setup(r => r.Get(It.IsAny <string>(), It.IsAny <CancellationToken>())).Returns(Task.FromResult(authenticationSchemeProvider));
            var jObj = new JObject();

            jObj.Add("Property", "value");
            jObj.Add("InvalidProperty1", "value");
            jObj.Add("InvalidProperty2", "value");

            // ACT
            var exception = await Assert.ThrowsAsync <OAuthException>(() => handler.Handle("id", jObj, CancellationToken.None));

            // ASSERT
            Assert.NotNull(exception);
        }
        public async Task <ActionResult> CreateAdmin(AdminViewModel viewModel)
        {
            if (viewModel.AdminPassword != viewModel.ConfirmPassword)
            {
                ViewBag.Languages = new SelectList(SupportedCultures.Cultures.Select(x => new { Value = x.TwoLetterISOLanguageName, Text = x.DisplayName }).ToList(), "Value", "Text");
                ModelState.AddModelError("ConfirmPassword", "Password does not match");
                return(View(viewModel));
            }

            SetupHelper.InitilizeDatabase();

            if (SetupHelper.IsDbCreateComplete == true && SetupHelper.IsAdminCreateComplete == false)
            {
                if (!ModelState.IsValid)
                {
                    ViewBag.Languages = new SelectList(SupportedCultures.Cultures.Select(x => new { Value = x.TwoLetterISOLanguageName, Text = x.DisplayName }).ToList(), "Value", "Text");
                    return(View(viewModel));
                }

                var optionBuilder = new DbContextOptionsBuilder <NccDbContext>();

                SupportedDatabases supportedDatabases = TypeConverter.TryParseDatabaseEnum(SetupHelper.SelectedDatabase);

                switch (supportedDatabases)
                {
                case SupportedDatabases.MSSQL:
                    optionBuilder.UseSqlServer(SetupHelper.ConnectionString, opts => opts.MigrationsAssembly("NetCoreCMS.Framework"));
                    break;

                case SupportedDatabases.MsSqlLocalStorage:
                    break;

                case SupportedDatabases.MySql:
                    optionBuilder.UseMySql(SetupHelper.ConnectionString, opts => opts.MigrationsAssembly("NetCoreCMS.Framework"));
                    break;

                case SupportedDatabases.SqLite:
                    optionBuilder.UseSqlite(SetupHelper.ConnectionString, opts => opts.MigrationsAssembly("NetCoreCMS.Framework"));
                    break;

                case SupportedDatabases.PgSql:
                    break;
                }

                var nccDbConetxt = new NccDbContext(optionBuilder.Options);

                var userStore              = new NccUserStore(nccDbConetxt);
                var identityOptions        = Options.Create(new IdentityOptions());
                var passwordHasher         = new PasswordHasher <NccUser>();
                var userValidatorList      = new List <UserValidator <NccUser> >();
                var passwordValidatorList  = new List <PasswordValidator <NccUser> >();
                var lookupNormalizer       = new UpperInvariantLookupNormalizer();
                var identityErrorDescriber = new IdentityErrorDescriber();
                var logger     = _loggerFactory.CreateLogger <UserManager <NccUser> >();
                var authOption = new AuthenticationOptions();
                var options    = Options.Create <AuthenticationOptions>(authOption);
                var scheme     = new AuthenticationSchemeProvider(options);

                var userManager = new UserManager <NccUser>(
                    userStore,
                    identityOptions,
                    passwordHasher,
                    userValidatorList,
                    passwordValidatorList,
                    lookupNormalizer,
                    identityErrorDescriber,
                    GlobalContext.App.ApplicationServices,
                    logger
                    );

                var roleStore         = new NccRoleStore(nccDbConetxt);
                var roleValidatorList = new List <RoleValidator <NccRole> >();
                var roleLogger        = _loggerFactory.CreateLogger <RoleManager <NccRole> >();

                var roleManager = new RoleManager <NccRole>(
                    roleStore,
                    roleValidatorList,
                    new UpperInvariantLookupNormalizer(),
                    new IdentityErrorDescriber(),
                    roleLogger
                    );

                var claimsFactory = new UserClaimsPrincipalFactory <NccUser, NccRole>(userManager, roleManager, identityOptions);
                var signInLogger  = _loggerFactory.CreateLogger <SignInManager <NccUser> >();
                var signInManager = new NccSignInManager <NccUser>(userManager, _httpContextAccessor, claimsFactory, identityOptions, signInLogger, scheme);

                //nccDbConetxt.Database.Migrate();

                var setupInfo = new WebSiteInfo()
                {
                    SiteName         = viewModel.SiteName,
                    Tagline          = viewModel.Tagline,
                    AdminPassword    = viewModel.AdminPassword,
                    AdminUserName    = viewModel.AdminUserName,
                    ConnectionString = SetupHelper.ConnectionString,
                    Database         = TypeConverter.TryParseDatabaseEnum(SetupHelper.SelectedDatabase),
                    Email            = viewModel.Email,
                    Language         = viewModel.Language,
                    TablePrefix      = viewModel.TablePrefix
                };

                //SetupHelper.RegisterAuthServices(supportedDatabases);
                var admin = await SetupHelper.CreateSuperAdminUser(nccDbConetxt, userManager, roleManager, signInManager, setupInfo);

                if (admin != null)
                {
                    SetupHelper.IsAdminCreateComplete = true;
                    SetupHelper.Language = viewModel.Language;
                    SetupHelper.SaveSetup();
                    SetupHelper.CrateNccWebSite(nccDbConetxt, setupInfo);

                    await SetupHelper.SaveBasicData(admin, nccDbConetxt, userManager, roleManager, signInManager, setupInfo);

                    return(Redirect("/Home/SetupSuccess"));
                }
                else
                {
                    TempData["ErrorMessage"] = "Could not create Admin user and Roles.";
                    return(Redirect("/Home/Error"));
                }
            }

            TempData["ErrorMessage"] = "Setup already completed.";
            return(Redirect("/Home/Error"));
        }
        /// <summary>
        /// 异步需求处理
        /// </summary>
        /// <param name="context"></param>
        /// <param name="requirement"></param>
        /// <returns></returns>
        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
        {
            /*
             * 首先必须在controller上配置Authorize,可以是策略授权,也可以是角色基本授权
             * 1、开启公约,startup中的全局授权过滤公约:o.Conventions.Insert(0, new GlobalRouteAuthorizeConvention());
             * 2、不开启公约,使用IHttpContextAccessor,也能实现效果
             */

            //更新最新的角色和接口列表
            var data = await RoleModulePermissionServices.GetRoleModule();

            var list = data.Where(w => w.IsDeleted == false).OrderBy(o => o.Id).Select(s => new PermissionItem()
            {
                Role = s.Role?.Name,
                Url  = s.Module?.LinkUrl,
            }).ToList();

            requirement.Permissions = list;

            //从AuthorizationHandlerContext转成HttpContext,以便取出表求信息
            //var filterContext = context.Resource as AuthorizationFilterContext;
            var httpContext = (context.Resource as AuthorizationFilterContext)?.HttpContext;

            if (httpContext == null)
            {
                httpContext = m_Accessor.HttpContext;
            }

            //请求Url
            if (httpContext != null)
            {
                var requestUrl = httpContext.Request.Path.Value.ToLower();
                //判断请求是否停止
                var handlers = httpContext.RequestServices.GetRequiredService <IAuthenticationHandlerProvider>();
                foreach (var scheme in await AuthenticationSchemeProvider.GetRequestHandlerSchemesAsync())
                {
                    if (await handlers.GetHandlerAsync(httpContext, scheme.Name) is IAuthenticationRequestHandler handler && await handler.HandleRequestAsync())
                    {
                        context.Fail();
                        return;
                    }
                }

                //判断请求是否拥有凭据,即有没有登陆
                var defaultAuthenticate = await AuthenticationSchemeProvider.GetDefaultAuthenticateSchemeAsync();

                if (defaultAuthenticate != null)
                {
                    var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);

                    //result.Princple不为空即登陆成功
                    if (result?.Principal != null)
                    {
                        httpContext.User = result.Principal;

                        //权限中是否存在请求的Url
                        //if (requirement.Permissions.GroupBy(g => g.Url).Where(w => w.Key?.ToLower() == requestUrl).Count() > 0)
                        if (true)
                        {
                            //获取当前用户的角色信息
                            var currentUserRoles = httpContext.User.Claims.Where(w => w.Type == requirement.ClaimType).Select(s => s.Value).ToList();

                            var isMatchRole     = false;
                            var permissionRoles = requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role));
                            foreach (var role in permissionRoles)
                            {
                                try
                                {
                                    if (Regex.Match(requestUrl, role.Url?.ObjToString().ToLower())?.Value == requestUrl)
                                    {
                                        isMatchRole = true;
                                        break;
                                    }
                                }
                                catch (RegexMatchTimeoutException ex)
                                {
                                    Console.WriteLine($"RegexMatchError: {ex.ToString()}");
                                }
                            }

                            //验证权限
                            //if(currentUserRoles.Count <= 0 || requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role) && w.Url.ToLower() == requestUrl).Count() <= 0)
                            if (currentUserRoles.Count <= 0 || !isMatchRole)
                            {
                                context.Fail();
                                return;
                            }
                        }

                        //判断过期时间(这里仅仅是最坏验证原则,你可以不要这个if else的判断,因为我们使用的官方验证,Token过期后上边的result?.Principal就为null了,讲不到这里,因此这里其实可以不用验证过期时间,只是做最后研究判断)
                        if ((httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) != null && DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now)
                        {
                            context.Succeed(requirement);
                        }
                        else
                        {
                            context.Fail();
                            return;
                        }
                        return;
                    }
                }

                //判断没有登陆时,是否访问登陆的url,并且是Post请求,form表单提交类型,否则为失败
                if (!requestUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") || !httpContext.Request.HasFormContentType))
                {
                    context.Fail();
                    return;
                }
            }

            context.Succeed(requirement);
        }
 public Task <bool> Update(AuthenticationSchemeProvider authenticationSchemeProvider, CancellationToken cancellationToken)
 {
     _dbContext.AuthenticationSchemeProviders.Update(authenticationSchemeProvider);
     return(Task.FromResult(true));
 }
Example #11
0
 public Task <bool> Update(AuthenticationSchemeProvider authenticationSchemeProvider, CancellationToken cancellationToken)
 {
     _authenticationSchemeProviders.Remove(_authenticationSchemeProviders.First(a => a.Id == authenticationSchemeProvider.Id));
     _authenticationSchemeProviders.Add((AuthenticationSchemeProvider)authenticationSchemeProvider.Clone());
     return(Task.FromResult(true));
 }