'How to get the current domain name in Startup.cs

I have a domain that has multiple sites underneath it.

In my Startup.cs I have the following code

public void ConfigureServices(IServiceCollection services)
{
    services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
    {
        options.Cookies.ApplicationCookie.CookieName = "MyAppName";
        options.Cookies.ApplicationCookie.ExpireTimeSpanTimeSpan.FromMinutes(300);
     })
     .AddEntityFrameworkStores<MyDbContext, Guid>()
     .AddDefaultTokenProviders();

On the production machine all my sites are in a subfolder under the same site in IIS so I don't want to use the default domain as the cookie name otherwise different sites cookies will have the same name

What I want is to get the current domain e..g mydomain.com and then append it to an explicit cookiename per site that I specify in Startup.cs e.g.

 var domain = "get the server domain here somehow e.g. domain.com";
 ...
 options.Cookies.ApplicationCookie.CookieName = "MyAppName." + domain;

How do I do this?

The reason I ask:

I can see in Chrome developer tools the cookies fall under separate domain names of the site I am accessing. However I sometimes somehow still get the situation of when I log into the same site on two different servers, that I can't log into one and it doesn't log any error. The only solution is to use another browser so I can only assume by the symptoms can only be to do with the cookie.

So my question is really just a personal preference question as in my environment I would prefer to append the domain name to the cookie name although the cookie can only belong to a specific domain.



Solution 1:[1]

First of all, i would store domain name in configuration. So it would enable me to change it for current environment.

options.Cookies.ApplicationCookie.CookieName = Configuration["DomainName"];

If you don't like this way you can override cookie option on signin event like this(i am not sure below ways are good):

Events = new CookieAuthenticationEvents()
{
   OnSigningIn = async (context) =>
   {
       context.Options.CookieName = "MyAppName." + context.HttpContext.Request.Host.Value.ToString();
   }
}

Or catch first request in configure and override options

        bool firstRequest = true;
        app.Use(async (context, next) =>
        {
            if(firstRequest)
            {
                options.CookieName = "MyAppName." + context.HttpContext.Request.Host.Value.ToString();
                firstRequest = false;
            }
            await next();
        });

Also see similar question How to get base url without accessing a request

Solution 2:[2]

I found this other way. also I have a blog to documented that.

public class Startup
    {
        public IConfiguration Configuration { get; }
        private WebDomainHelper DomainHelper;

        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpContextAccessor();
            services.AddScoped(sp => new HttpClient() { BaseAddress = new Uri(DomainHelper.GetDomain()) });
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            DomainHelper = new WebDomainHelper(app.ApplicationServices.GetRequiredService());

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseEndpoints(
                endpoints =>
                {
                    endpoints.MapControllerRoute("default", "{controller=Account}/{action=Index}/{id?}");
                }
            );
        }
    }



    public class WebDomainHelper
    {
        IHttpContextAccessor ContextAccessor;
        public WebDomainHelper(IHttpContextAccessor contextAccessor)
        {
            ContextAccessor = contextAccessor;
        }

        /// 

        /// Get domain name
        /// 

        public string GetDomain()
        {
            string serverURL;
            try
            {
                serverURL = $"{ContextAccessor.HttpContext.Request.Scheme}://{ContextAccessor.HttpContext.Request.Host.Value}/";
            }
            catch
            {
                serverURL = string.Empty;
            }
            return serverURL;
        }
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 DrUalcman