1
\$\begingroup\$

The below code works but there's a lot of duplication I wonder if I can get around.

I would like to be able to use .AddDeveloperSigningCredential(false) if in development environment, otherwise set a certificate collection object and use .AddSigningCredential(certCollection[0])

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<RSNROAuthContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("RSNRAccountDB")));

        services.AddScoped(typeof(IUserProfileRepository), typeof(UserProfileRepository));

        services.AddIdentity<User, IdentityRole>(config =>
            {
                config.SignIn.RequireConfirmedEmail = true;
            })
            .AddEntityFrameworkStores<RSNROAuthContext>()
            .AddDefaultTokenProviders();

        // Add application services.
        services.AddTransient<IEmailSender, EmailSender>();
        services.AddTransient<IProfileService, ProfileService>();

        services.AddMvc();

        string connectionString = Configuration.GetConnectionString("RSNRAccountDB");

        X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        certStore.Open(OpenFlags.ReadOnly);

        if (Env.IsDevelopment())
        {
            // configure identity server with in-memory stores, keys, clients and scopes
            services.AddIdentityServer()

                .AddDeveloperSigningCredential(false)
                .AddAspNetIdentity<User>()
                // this adds the config data from DB (clients, resources)
                .AddConfigurationStore(options =>
                {
                    options.ConfigureDbContext = builder =>
                        builder.UseSqlServer(connectionString,
                            sql => sql.MigrationsAssembly("RSNR.OAuth.DAL"));
                })
                // this adds the operational data from DB (codes, tokens, consents)
                .AddOperationalStore(options =>
                {
                    options.ConfigureDbContext = builder =>
                        builder.UseSqlServer(connectionString,
                            sql => sql.MigrationsAssembly("RSNR.OAuth.DAL"));

                    // this enables automatic token cleanup. this is optional.
                    options.EnableTokenCleanup = true;
                    options.TokenCleanupInterval = 30;
                })
                .AddProfileService<ProfileService>();
            }
        else
        {
            X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, Configuration["WEBSITE_LOAD_CERTIFICATES"], false);

            // configure identity server with in-memory stores, keys, clients and scopes
            services.AddIdentityServer()
                .AddSigningCredential(certCollection[0])

                .AddAspNetIdentity<User>()
                // this adds the config data from DB (clients, resources)
                .AddConfigurationStore(options =>
                {
                    options.ConfigureDbContext = builder =>
                        builder.UseSqlServer(connectionString,
                            sql => sql.MigrationsAssembly("RSNR.OAuth.DAL"));
                })
                // this adds the operational data from DB (codes, tokens, consents)
                .AddOperationalStore(options =>
                {
                    options.ConfigureDbContext = builder =>
                        builder.UseSqlServer(connectionString,
                            sql => sql.MigrationsAssembly("RSNR.OAuth.DAL"));

                    // this enables automatic token cleanup. this is optional.
                    options.EnableTokenCleanup = true;
                    options.TokenCleanupInterval = 30;
                })
                .AddProfileService<ProfileService>();

        }

            services.Configure<AuthMessageSenderOptions>(Configuration);
            services.Configure<ClientOptions>(Configuration);
    }
\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

There is a lot of repeated code in the if and the else branch which can be extracted. Assuming the services.XXX() methods are using fluent style and every call returns a IServiceCollection it could look like so

    IIdentityServerBuilder serverBuilder = services.AddIdentityServer();

    if (Env.IsDevelopment())
    {
        // configure identity server with in-memory stores, keys, clients and scopes
            serverBuilder.AddDeveloperSigningCredential(false);
    }
    else
    {
        X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, Configuration["WEBSITE_LOAD_CERTIFICATES"], false);

        // configure identity server with in-memory stores, keys, clients and scopes
        serverBuilder.AddSigningCredential(certCollection[0]);
    }

    serverBuilder.AddAspNetIdentity<User>()
    // this adds the config data from DB (clients, resources)
    .AddConfigurationStore(options =>
    {
        options.ConfigureDbContext = builder =>
            builder.UseSqlServer(connectionString,
                sql => sql.MigrationsAssembly("RSNR.OAuth.DAL"));
    })
    // this adds the operational data from DB (codes, tokens, consents)
    .AddOperationalStore(options =>
    {
        options.ConfigureDbContext = builder =>
            builder.UseSqlServer(connectionString,
                sql => sql.MigrationsAssembly("RSNR.OAuth.DAL"));

        // this enables automatic token cleanup. this is optional.
        options.EnableTokenCleanup = true;
        options.TokenCleanupInterval = 30;
    })
    .AddProfileService<ProfileService>();
\$\endgroup\$
9
  • \$\begingroup\$ thanks for the suggestion however the likes of AddSigningCredential needs to chain on to AddIndentityServer() - otherwise I get could not resolve symbol syntax error on AddSigningCredential etc. \$\endgroup\$
    – egmfrs
    Mar 14, 2018 at 15:56
  • \$\begingroup\$ So what does AddIdentityServer() return ? \$\endgroup\$
    – Heslacher
    Mar 14, 2018 at 15:58
  • \$\begingroup\$ if I peek the definition, it says: public static IIdentityServerBuilder AddIdentityServer(this IServiceCollection services); \$\endgroup\$
    – egmfrs
    Mar 14, 2018 at 16:06
  • \$\begingroup\$ And what returns AddDeveloperSigningCredential() and AddSigningCredential() ? \$\endgroup\$
    – Heslacher
    Mar 14, 2018 at 16:09
  • 1
    \$\begingroup\$ Should work now \$\endgroup\$
    – Heslacher
    Mar 14, 2018 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.