4

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.

dfmetro
  • 4,462
  • 8
  • 39
  • 65
  • If they have separate domain names the cookies are already separated. I don't really get the actual problem – Sami Kuhmonen Oct 13 '16 at 11:51
  • Yes the cookies are separate underneath each domain if I look in Chrome dev tools. Let just say I want to do this not for a specific reason but just so the cookie name includes the domain name for my personal preference – dfmetro Oct 13 '16 at 12:23

2 Answers2

2

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

Community
  • 1
  • 1
adem caglin
  • 22,700
  • 10
  • 58
  • 78
  • I recently moved to Docker. While my webserver listens to localhost:5000, it is actually hosted on :80, therefore it has little use to check the hosting parameters from Startup.cs. So for me the configuration setting is the best, easiest and most flexible way. – Rob van der Veer Jun 13 '17 at 19:59
  • @Rob van der Veer, it can be the best, as you said, for your case but not for everyone because there are applications that serve more than one domain. – Serg Jan 20 '18 at 11:45
0

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;
        }
    }
DrUalcman
  • 1
  • 2