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); } }
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); }
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); }
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)); }
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)); }
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)); }