public static PasswordlessLoginBuilder AddMySql(this PasswordlessLoginBuilder builder,
                                                        Action <DbContextOptionsBuilder> options)
        {
            builder.Services.AddDbContext <PasswordlessLoginDbContext>(options);

            return(builder);
        }
コード例 #2
0
        public static PasswordlessLoginBuilder AddSmtpEmail(this PasswordlessLoginBuilder builder, SmtpOptions smtpOptions)
        {
            builder.Services.AddSingleton(smtpOptions);
            builder.Services.AddTransient <IEmailService, SmtpEmailService>();

            return(builder);
        }
コード例 #3
0
        public static PasswordlessLoginBuilder AddSmtpEmail(this PasswordlessLoginBuilder builder, IConfiguration configuration)
        {
            var smtpOptions = new SmtpOptions();

            configuration.Bind(smtpOptions);

            return(builder.AddSmtpEmail(smtpOptions));
        }
コード例 #4
0
        public static PasswordlessLoginBuilder AddSmtpEmail(this PasswordlessLoginBuilder builder, Action <SmtpOptions> smtpOptionsBuilder)
        {
            var smtpOptions = new SmtpOptions();

            smtpOptionsBuilder?.Invoke(smtpOptions);

            return(builder.AddSmtpEmail(smtpOptions));
        }
        public static PasswordlessLoginBuilder AddPasswordlessLogin(this IServiceCollection services, IConfiguration configuration)
        {
            var passwordlessLoginOptions = new PasswordlessLoginOptions();

            configuration.Bind(passwordlessLoginOptions);
            var builder = new PasswordlessLoginBuilder(services, passwordlessLoginOptions);

            return(builder.AddPasswordlessLogin());
        }
        public static PasswordlessLoginBuilder AddPasswordlessLogin(this IServiceCollection services, Action <PasswordlessLoginOptions> optionsAction = null)
        {
            var passwordlessLoginOptions = new PasswordlessLoginOptions();

            optionsAction?.Invoke(passwordlessLoginOptions);

            var builder = new PasswordlessLoginBuilder(services, passwordlessLoginOptions);

            return(builder.AddPasswordlessLogin());
        }
コード例 #7
0
        public static PasswordlessLoginBuilder AddPasswordlessLoginAPI(this PasswordlessLoginBuilder builder, string[] apiAllowedOrigins = null)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }

            builder.Services.AddPasswordlessCorsPolicy(apiAllowedOrigins);

            return(builder);
        }
コード例 #8
0
        public static PasswordlessLoginBuilder AddAuth(this PasswordlessLoginBuilder builder)
        {
            builder.Services
            .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options =>
            {
                options.ExpireTimeSpan = TimeSpan.FromMinutes(builder.Options.DefaultSessionLengthMinutes);
                options.ConfigurePasswordlessAuthenticationOptions(builder.Options.Urls);
            });

            return(builder);
        }
コード例 #9
0
        public static PasswordlessLoginBuilder AddCustomEmailTemplates(this PasswordlessLoginBuilder builder, string templateOverrideFolder, CultureInfo[] supportedCultures = null)
        {
            if (!Directory.Exists(templateOverrideFolder ?? throw new ArgumentNullException(nameof(templateOverrideFolder))))
            {
                throw new Exception($"Custom email template folder '{templateOverrideFolder}' does not exist.");
            }

            IFileProvider templateFileProvider = new CompositeFileProvider(
                new PhysicalFileProvider(templateOverrideFolder),
                TemplateFileProvider
                );


            return(builder.AddEmailTemplates(templateFileProvider, supportedCultures, true));
        }
コード例 #10
0
        private static PasswordlessLoginBuilder AddEmailTemplates(this PasswordlessLoginBuilder builder, IFileProvider templateFileProvider, CultureInfo[] supportedCultures = null, bool force = false)
        {
            var emailTemplates = EmailTemplateProcessor.GetTemplates(templateFileProvider, supportedCultures);

            if (force)
            {
                builder.Services.AddSingleton(emailTemplates);
            }
            else
            {
                builder.Services.TryAddSingleton(emailTemplates);
            }

            return(builder);
        }
        public static PasswordlessLoginBuilder AddSqlServer(this PasswordlessLoginBuilder builder, 
            Action<DbContextOptionsBuilder> options,
            SqlServerPasswordlessDatabaseConfig config = null
            )
        {
            builder.Services.AddSingleton(config ?? new SqlServerPasswordlessDatabaseConfig());

            // First register the inherited db context. However, this registers 
            // DbContextOptions<SqlServerPasswordlessLoginDbContext> which can't be passed to be base class,
            // so we use the "hack" below to register DbContextOptions<PasswordlessLoginDbContext>.
            builder.Services.AddDbContext<PasswordlessLoginDbContext, SqlServerPasswordlessLoginDbContext>(options);

            // Register the base db context in order to register DbContextOptions<PasswordlessLoginDbContext>.
            // PasswordlessLoginDbContext won't actually be used since we already registed a different implementation above.
            builder.Services.AddDbContext<PasswordlessLoginDbContext>(options);

            return builder;
        }
        /// <summary>
        /// Adds ability to use views embedded in packages. Add before calling services.UseMvc() or services.UseEndpoints().
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static PasswordlessLoginBuilder AddOpenIdAuthorityUI(this PasswordlessLoginBuilder builder)
        {
            var assembly = typeof(PasswordlessLoginBuilderExtensionsOpenIdAuthorityAPI).GetTypeInfo().Assembly;

            var embeddedFileProvider = new EmbeddedFileProvider(assembly, "SimpleIAM.OpenIdAuthority.UI.UI");

            builder.Services.AddControllersWithViews()
            .AddRazorRuntimeCompilation(options => options.FileProviders.Add(embeddedFileProvider));

            builder.Services.Configure <RazorViewEngineOptions>(options =>
            {
                options.ViewLocationExpanders.Add(new EmbeddedViewLocator());
            });

            builder.Services.TryAddSingleton <ITempDataProvider, CookieTempDataProvider>();

            return(builder);
        }
コード例 #13
0
        public static PasswordlessLoginBuilder AddPasswordlessLogin(this PasswordlessLoginBuilder builder)
        {
            var services = builder.Services;

            services.AddSingleton(builder.Options);

            services.TryAddTransient <IEventNotificationService, DefaultEventNotificationService>();
            services.TryAddTransient <IOneTimeCodeStore, DbOneTimeCodeStore>();
            services.TryAddTransient <IOneTimeCodeService, OneTimeCodeService>();
            services.TryAddTransient <IUserStore, DbUserStore>();
            services.TryAddTransient <ITrustedBrowserStore, DbTrustedBrowserStore>();
            services.TryAddTransient <IMessageService, MessageService>();
            services.TryAddTransient <ISignInService, PasswordlessSignInService>();
            services.TryAddTransient <IApplicationService, NonexistantApplicationService>();

            services.TryAddSingleton <IPasswordHashService>(
                new AspNetIdentityPasswordHashService(PasswordlessLoginConstants.Security.DefaultPbkdf2Iterations));
            services.TryAddTransient <IPasswordHashStore, DbPasswordHashStore>();
            services.TryAddTransient <IPasswordService, DefaultPasswordService>();
            services.TryAddTransient <IApplicationLocalizer, DefaultLocalizer>();

            services.TryAddTransient <AuthenticateOrchestrator>();
            services.TryAddTransient <UserOrchestrator>();

            services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>();

            // IUrlHelper
            services.TryAddSingleton <IActionContextAccessor, ActionContextAccessor>();
            services.TryAddScoped <IUrlHelper>(x =>
            {
                var actionContext = x.GetRequiredService <IActionContextAccessor>().ActionContext;
                var factory       = x.GetRequiredService <IUrlHelperFactory>();
                return(factory.GetUrlHelper(actionContext));
            });

            services.TryAddScoped <IUrlService, PasswordlessUrlService>();

            builder.AddEmailTemplates(TemplateFileProvider);
            builder.Services.TryAddTransient <IEmailTemplateService, EmailTemplateService>();

            return(builder);
        }
        public static PasswordlessLoginBuilder AddOpenIdAuthority(this PasswordlessLoginBuilder builder, IConfiguration configuration)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            var hostingConfig = new HostingConfig();

            configuration.Bind(OpenIdAuthorityConstants.ConfigurationSections.Hosting, hostingConfig);
            builder.Services.AddSingleton(hostingConfig);

            var appConfigs = configuration.GetAppConfigs();
            var appService = new DefaultApplicationService(appConfigs);

            builder.Services.TryAddSingleton <IApplicationService>(appService);

            var clients  = AppConfigHelper.GetClientsFromAppConfig(appConfigs);
            var apps     = AppConfigHelper.GetAppsFromClients(clients);
            var appStore = new InMemoryAppStore(apps);

            builder.Services.TryAddSingleton <IAppStore>(appStore);

            var idScopeConfig = configuration.GetSection(OpenIdAuthorityConstants.ConfigurationSections.IdScopes).Get <List <IdScopeConfig> >() ?? new List <IdScopeConfig>();
            var idScopes      = idScopeConfig.Select(x => new IdentityResource(x.Name, x.IncludeClaimTypes)
            {
                Required = x.Required
            }).ToList();

            idScopes.AddRange(new List <IdentityResource>()
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email(),
                new IdentityResources.Phone(),
                new IdentityResources.Address(),
            });

            var apiConfigs   = configuration.GetSection(OpenIdAuthorityConstants.ConfigurationSections.Apis).Get <List <ApiConfig> >() ?? new List <ApiConfig>();
            var apiResources = apiConfigs.Select(x => new ApiResource(x.Url, x.IncludeClaimTypes)
            {
                ApiSecrets = x.Secrets?.ToList()?.Select(y => new Secret(y.Sha256())).ToList(),
                Scopes     = x.Scopes?.ToList()?.Select(y => new Scope(y)).ToList()
            }).ToList();

            builder.Services.AddTransient <ISignInService, OpenIdAuthoritySignInService>(); // NOTE: This must replace the service registered by PasswordlessLogin
            builder.Services.TryAddTransient <SimpleIAM.PasswordlessLogin.Services.Password.IReadOnlyPasswordService, SimpleIAM.PasswordlessLogin.Services.Password.DefaultPasswordService>();
            builder.Services.TryAddTransient <IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();

            builder.Services.AddIdentityServer(options =>
            {
                options.UserInteraction.LoginUrl          = builder.Options.Urls.SignIn;
                options.UserInteraction.LogoutUrl         = builder.Options.Urls.SignOut;
                options.UserInteraction.LogoutIdParameter = OpenIdAuthorityConstants.Configuration.LogoutIdParameter;
                options.UserInteraction.ErrorUrl          = builder.Options.Urls.Error;
                options.Authentication.CookieLifetime     = TimeSpan.FromMinutes(builder.Options.DefaultSessionLengthMinutes);
            })
            .AddDeveloperSigningCredential()     //todo: replace
            .AddInMemoryApiResources(apiResources)
            .AddInMemoryClients(clients)
            .AddProfileService <ProfileService>()
            .AddInMemoryIdentityResources(idScopes);

            builder.Services.AddSingleton <IConfigureOptions <CookieAuthenticationOptions>, ReconfigureCookieOptions>();

            return(builder);
        }