AD Login failure when using Docker and multiple replicasHow is Docker different from a virtual machine?Should I use Vagrant or Docker for creating an isolated environment?How to list containers in DockerHow to get a Docker container's IP address from the host?How to remove old Docker containersHow to deal with persistent storage (e.g. databases) in DockerCopying files from Docker container to hostCopying files from host to Docker containerHow to copy Docker images from one host to another without using a repositoryFrom inside of a Docker container, how do I connect to the localhost of the machine?
Was planting UN flag on Moon ever discussed?
Entered UK using my now-lost UK passport; can I go to Spain using my US passport?
Is it true that "only photographers care about noise"?
C++ logging library
How to befriend someone who doesn't like to talk?
How to make a composition of functions prettier?
Why vspace-lineskip removes space after tikz picture although it stands before the picture?
In American Politics, why is the Justice Department under the President?
Why is my power MOSFET heating up when on?
In The Incredibles 2, why does Screenslaver's name use a pun on something that doesn't exist in the 1950s pastiche?
Parsing text written the millitext font
How do I avoid typing "git" at the begining of every Git command?
DateTime.addMonths skips a month (from feb to mar)
Forgot passport for Alaska cruise (Anchorage to Vancouver)
A life of PhD: is it feasible?
Prove that the infinite series equals 1
Placement of positioning lights on A320 winglets
Savage Road Signs
Playing a trill with grace note ending
Makefile for a simple Debian Repo
Should I be able to use the Gloom Stalker ranger's Dread Ambusher class feature when attacking before initiative has been rolled to add a d8 damage?
Why did Robert pick unworthy men for the White Cloaks?
What is the STRONGEST end-of-line knot to use if you want to use a steel-thimble at the end, so that you've got a steel-eyelet at the end of the line?
Create a cube from identical 3D objects
AD Login failure when using Docker and multiple replicas
How is Docker different from a virtual machine?Should I use Vagrant or Docker for creating an isolated environment?How to list containers in DockerHow to get a Docker container's IP address from the host?How to remove old Docker containersHow to deal with persistent storage (e.g. databases) in DockerCopying files from Docker container to hostCopying files from host to Docker containerHow to copy Docker images from one host to another without using a repositoryFrom inside of a Docker container, how do I connect to the localhost of the machine?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I have an nginx reverse proxy sitting in front of an aspnetcore application that authenticates against AzureAD, When I run in a swarm with a single replica all works fine, however when I have more than 1 replica I get the following Error
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Below is my Startup.cs
using System.IO;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using DataAccess.Models;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.HttpOverrides;
using System.Globalization;
using Microsoft.Net.Http.Headers;
using System.Data.SqlClient;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Newtonsoft.Json;
using System.Linq;
namespace www
public class Startup
public Startup(IConfiguration configuration)
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
Configuration = configuration;
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
;
Configuration = builder.Build();
TradingContext.ConnectionString = $"Server=Configuration.GetSection("SQL_SERVER").Value;Database=Trading;User ID=Configuration.GetSection("SQL_USER").Value;Password=Configuration.GetSection("SQL_PASSWORD").Value;MultipleActiveResultSets=true;";
public IConfiguration Configuration get;
public void ConfigureServices(IServiceCollection services)
services.AddHealthChecks()
.AddCheck("SqlServer", () =>
try
using (var db = new TradingContext())
var x = db.InstrumentRoots.Count();
catch
return HealthCheckResult.Unhealthy();
return HealthCheckResult.Healthy();
);
services.AddMvc().AddJsonOptions(options =>
var resolver = options.SerializerSettings.ContractResolver;
if (resolver != null)
var res = (DefaultContractResolver)resolver;
res.NamingStrategy = null;
);
services.Configure<ForwardedHeadersOptions>(options =>
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor );
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
services.AddTransient<IEmailSender, AuthMessageSender>();
services.Configure<CookiePolicyOptions>(options =>
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.None;
);
services.AddDbContext<TradingContext>();
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.AddMvc(options =>
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
)
.AddRazorPagesOptions(options =>
options.Conventions.AddPageRoute("/Dashboard/Index", "");
)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Error");
var options = new HealthCheckOptions();
options.ResponseWriter = async (c, r) =>
c.Response.ContentType = "application/json";
var result = JsonConvert.SerializeObject(new
status = r.Status.ToString(),
errors = r.Entries.Select(e => new key = e.Key, value = e.Value.Status.ToString() )
);
await c.Response.WriteAsync(result);
;
app.UseHealthChecks("/healthcheck", options);
app.UseCookiePolicy();
app.UseStaticFiles(new StaticFileOptions
OnPrepareResponse = ctx =>
const int durationInSeconds = 60 * 60 * 24;
ctx.Context.Response.Headers[HeaderNames.CacheControl] =
"public,max-age=" + durationInSeconds;
);
var fordwardedHeaderOptions = new ForwardedHeadersOptions ForwardedHeaders.XForwardedProto
;
fordwardedHeaderOptions.KnownNetworks.Clear();
fordwardedHeaderOptions.KnownProxies.Clear();
app.UseForwardedHeaders(fordwardedHeaderOptions);
app.UseAuthentication();
app.UseMvc();
Below is my nginx.config
events
http
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
large_client_header_buffers 4 16k;
gzip on;
server
listen 80;
listen [::]:80;
server_name xxxx;
location /
rewrite ^ https://$host$request_uri? permanent;
#for certbot challenges (renewal process)
location ~ /.well-known/acme-challenge
allow all;
root /data/letsencrypt;
#https://xxxx
server
server_name xxxx;
listen 443 ssl http2;
server_tokens off;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4;
ssl_certificate /etc/letsencrypt/live/xxxxx/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxxxx/privkey.pem;
location /
proxy_pass http://www:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
#security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
#CSP
#add_header Content-Security-Policy "frame-src 'self'; default-src 'self'; script-src 'self' 'unsafe-inline' https://maxcdn.bootstrapcdn.com https://ajax.googleapis.com; img-src 'self'; style-src 'self' https://maxcdn.bootstrapcdn.com; font-src 'self' data: https://maxcdn.bootstrapcdn.com; form-action 'self'; upgrade-insecure-requests;" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Any Idea what I am missing?
docker nginx .net-core azure-active-directory docker-swarm
add a comment |
I have an nginx reverse proxy sitting in front of an aspnetcore application that authenticates against AzureAD, When I run in a swarm with a single replica all works fine, however when I have more than 1 replica I get the following Error
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Below is my Startup.cs
using System.IO;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using DataAccess.Models;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.HttpOverrides;
using System.Globalization;
using Microsoft.Net.Http.Headers;
using System.Data.SqlClient;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Newtonsoft.Json;
using System.Linq;
namespace www
public class Startup
public Startup(IConfiguration configuration)
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
Configuration = configuration;
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
;
Configuration = builder.Build();
TradingContext.ConnectionString = $"Server=Configuration.GetSection("SQL_SERVER").Value;Database=Trading;User ID=Configuration.GetSection("SQL_USER").Value;Password=Configuration.GetSection("SQL_PASSWORD").Value;MultipleActiveResultSets=true;";
public IConfiguration Configuration get;
public void ConfigureServices(IServiceCollection services)
services.AddHealthChecks()
.AddCheck("SqlServer", () =>
try
using (var db = new TradingContext())
var x = db.InstrumentRoots.Count();
catch
return HealthCheckResult.Unhealthy();
return HealthCheckResult.Healthy();
);
services.AddMvc().AddJsonOptions(options =>
var resolver = options.SerializerSettings.ContractResolver;
if (resolver != null)
var res = (DefaultContractResolver)resolver;
res.NamingStrategy = null;
);
services.Configure<ForwardedHeadersOptions>(options =>
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor );
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
services.AddTransient<IEmailSender, AuthMessageSender>();
services.Configure<CookiePolicyOptions>(options =>
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.None;
);
services.AddDbContext<TradingContext>();
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.AddMvc(options =>
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
)
.AddRazorPagesOptions(options =>
options.Conventions.AddPageRoute("/Dashboard/Index", "");
)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Error");
var options = new HealthCheckOptions();
options.ResponseWriter = async (c, r) =>
c.Response.ContentType = "application/json";
var result = JsonConvert.SerializeObject(new
status = r.Status.ToString(),
errors = r.Entries.Select(e => new key = e.Key, value = e.Value.Status.ToString() )
);
await c.Response.WriteAsync(result);
;
app.UseHealthChecks("/healthcheck", options);
app.UseCookiePolicy();
app.UseStaticFiles(new StaticFileOptions
OnPrepareResponse = ctx =>
const int durationInSeconds = 60 * 60 * 24;
ctx.Context.Response.Headers[HeaderNames.CacheControl] =
"public,max-age=" + durationInSeconds;
);
var fordwardedHeaderOptions = new ForwardedHeadersOptions ForwardedHeaders.XForwardedProto
;
fordwardedHeaderOptions.KnownNetworks.Clear();
fordwardedHeaderOptions.KnownProxies.Clear();
app.UseForwardedHeaders(fordwardedHeaderOptions);
app.UseAuthentication();
app.UseMvc();
Below is my nginx.config
events
http
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
large_client_header_buffers 4 16k;
gzip on;
server
listen 80;
listen [::]:80;
server_name xxxx;
location /
rewrite ^ https://$host$request_uri? permanent;
#for certbot challenges (renewal process)
location ~ /.well-known/acme-challenge
allow all;
root /data/letsencrypt;
#https://xxxx
server
server_name xxxx;
listen 443 ssl http2;
server_tokens off;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4;
ssl_certificate /etc/letsencrypt/live/xxxxx/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxxxx/privkey.pem;
location /
proxy_pass http://www:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
#security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
#CSP
#add_header Content-Security-Policy "frame-src 'self'; default-src 'self'; script-src 'self' 'unsafe-inline' https://maxcdn.bootstrapcdn.com https://ajax.googleapis.com; img-src 'self'; style-src 'self' https://maxcdn.bootstrapcdn.com; font-src 'self' data: https://maxcdn.bootstrapcdn.com; form-action 'self'; upgrade-insecure-requests;" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Any Idea what I am missing?
docker nginx .net-core azure-active-directory docker-swarm
add a comment |
I have an nginx reverse proxy sitting in front of an aspnetcore application that authenticates against AzureAD, When I run in a swarm with a single replica all works fine, however when I have more than 1 replica I get the following Error
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Below is my Startup.cs
using System.IO;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using DataAccess.Models;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.HttpOverrides;
using System.Globalization;
using Microsoft.Net.Http.Headers;
using System.Data.SqlClient;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Newtonsoft.Json;
using System.Linq;
namespace www
public class Startup
public Startup(IConfiguration configuration)
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
Configuration = configuration;
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
;
Configuration = builder.Build();
TradingContext.ConnectionString = $"Server=Configuration.GetSection("SQL_SERVER").Value;Database=Trading;User ID=Configuration.GetSection("SQL_USER").Value;Password=Configuration.GetSection("SQL_PASSWORD").Value;MultipleActiveResultSets=true;";
public IConfiguration Configuration get;
public void ConfigureServices(IServiceCollection services)
services.AddHealthChecks()
.AddCheck("SqlServer", () =>
try
using (var db = new TradingContext())
var x = db.InstrumentRoots.Count();
catch
return HealthCheckResult.Unhealthy();
return HealthCheckResult.Healthy();
);
services.AddMvc().AddJsonOptions(options =>
var resolver = options.SerializerSettings.ContractResolver;
if (resolver != null)
var res = (DefaultContractResolver)resolver;
res.NamingStrategy = null;
);
services.Configure<ForwardedHeadersOptions>(options =>
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor );
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
services.AddTransient<IEmailSender, AuthMessageSender>();
services.Configure<CookiePolicyOptions>(options =>
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.None;
);
services.AddDbContext<TradingContext>();
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.AddMvc(options =>
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
)
.AddRazorPagesOptions(options =>
options.Conventions.AddPageRoute("/Dashboard/Index", "");
)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Error");
var options = new HealthCheckOptions();
options.ResponseWriter = async (c, r) =>
c.Response.ContentType = "application/json";
var result = JsonConvert.SerializeObject(new
status = r.Status.ToString(),
errors = r.Entries.Select(e => new key = e.Key, value = e.Value.Status.ToString() )
);
await c.Response.WriteAsync(result);
;
app.UseHealthChecks("/healthcheck", options);
app.UseCookiePolicy();
app.UseStaticFiles(new StaticFileOptions
OnPrepareResponse = ctx =>
const int durationInSeconds = 60 * 60 * 24;
ctx.Context.Response.Headers[HeaderNames.CacheControl] =
"public,max-age=" + durationInSeconds;
);
var fordwardedHeaderOptions = new ForwardedHeadersOptions ForwardedHeaders.XForwardedProto
;
fordwardedHeaderOptions.KnownNetworks.Clear();
fordwardedHeaderOptions.KnownProxies.Clear();
app.UseForwardedHeaders(fordwardedHeaderOptions);
app.UseAuthentication();
app.UseMvc();
Below is my nginx.config
events
http
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
large_client_header_buffers 4 16k;
gzip on;
server
listen 80;
listen [::]:80;
server_name xxxx;
location /
rewrite ^ https://$host$request_uri? permanent;
#for certbot challenges (renewal process)
location ~ /.well-known/acme-challenge
allow all;
root /data/letsencrypt;
#https://xxxx
server
server_name xxxx;
listen 443 ssl http2;
server_tokens off;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4;
ssl_certificate /etc/letsencrypt/live/xxxxx/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxxxx/privkey.pem;
location /
proxy_pass http://www:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
#security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
#CSP
#add_header Content-Security-Policy "frame-src 'self'; default-src 'self'; script-src 'self' 'unsafe-inline' https://maxcdn.bootstrapcdn.com https://ajax.googleapis.com; img-src 'self'; style-src 'self' https://maxcdn.bootstrapcdn.com; font-src 'self' data: https://maxcdn.bootstrapcdn.com; form-action 'self'; upgrade-insecure-requests;" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Any Idea what I am missing?
docker nginx .net-core azure-active-directory docker-swarm
I have an nginx reverse proxy sitting in front of an aspnetcore application that authenticates against AzureAD, When I run in a swarm with a single replica all works fine, however when I have more than 1 replica I get the following Error
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler<TOptions>.HandleRequestAsync()
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Builder.Extensions.MapWhenMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Below is my Startup.cs
using System.IO;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using DataAccess.Models;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.HttpOverrides;
using System.Globalization;
using Microsoft.Net.Http.Headers;
using System.Data.SqlClient;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Newtonsoft.Json;
using System.Linq;
namespace www
public class Startup
public Startup(IConfiguration configuration)
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
Configuration = configuration;
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
;
Configuration = builder.Build();
TradingContext.ConnectionString = $"Server=Configuration.GetSection("SQL_SERVER").Value;Database=Trading;User ID=Configuration.GetSection("SQL_USER").Value;Password=Configuration.GetSection("SQL_PASSWORD").Value;MultipleActiveResultSets=true;";
public IConfiguration Configuration get;
public void ConfigureServices(IServiceCollection services)
services.AddHealthChecks()
.AddCheck("SqlServer", () =>
try
using (var db = new TradingContext())
var x = db.InstrumentRoots.Count();
catch
return HealthCheckResult.Unhealthy();
return HealthCheckResult.Healthy();
);
services.AddMvc().AddJsonOptions(options =>
var resolver = options.SerializerSettings.ContractResolver;
if (resolver != null)
var res = (DefaultContractResolver)resolver;
res.NamingStrategy = null;
);
services.Configure<ForwardedHeadersOptions>(options =>
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor );
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
services.AddTransient<IEmailSender, AuthMessageSender>();
services.Configure<CookiePolicyOptions>(options =>
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.None;
);
services.AddDbContext<TradingContext>();
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.AddMvc(options =>
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
)
.AddRazorPagesOptions(options =>
options.Conventions.AddPageRoute("/Dashboard/Index", "");
)
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Error");
var options = new HealthCheckOptions();
options.ResponseWriter = async (c, r) =>
c.Response.ContentType = "application/json";
var result = JsonConvert.SerializeObject(new
status = r.Status.ToString(),
errors = r.Entries.Select(e => new key = e.Key, value = e.Value.Status.ToString() )
);
await c.Response.WriteAsync(result);
;
app.UseHealthChecks("/healthcheck", options);
app.UseCookiePolicy();
app.UseStaticFiles(new StaticFileOptions
OnPrepareResponse = ctx =>
const int durationInSeconds = 60 * 60 * 24;
ctx.Context.Response.Headers[HeaderNames.CacheControl] =
"public,max-age=" + durationInSeconds;
);
var fordwardedHeaderOptions = new ForwardedHeadersOptions ForwardedHeaders.XForwardedProto
;
fordwardedHeaderOptions.KnownNetworks.Clear();
fordwardedHeaderOptions.KnownProxies.Clear();
app.UseForwardedHeaders(fordwardedHeaderOptions);
app.UseAuthentication();
app.UseMvc();
Below is my nginx.config
events
http
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
large_client_header_buffers 4 16k;
gzip on;
server
listen 80;
listen [::]:80;
server_name xxxx;
location /
rewrite ^ https://$host$request_uri? permanent;
#for certbot challenges (renewal process)
location ~ /.well-known/acme-challenge
allow all;
root /data/letsencrypt;
#https://xxxx
server
server_name xxxx;
listen 443 ssl http2;
server_tokens off;
ssl_buffer_size 8k;
ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
ssl_ecdh_curve secp384r1;
ssl_session_tickets off;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4;
ssl_certificate /etc/letsencrypt/live/xxxxx/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxxxx/privkey.pem;
location /
proxy_pass http://www:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
#security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
#CSP
#add_header Content-Security-Policy "frame-src 'self'; default-src 'self'; script-src 'self' 'unsafe-inline' https://maxcdn.bootstrapcdn.com https://ajax.googleapis.com; img-src 'self'; style-src 'self' https://maxcdn.bootstrapcdn.com; font-src 'self' data: https://maxcdn.bootstrapcdn.com; form-action 'self'; upgrade-insecure-requests;" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Any Idea what I am missing?
docker nginx .net-core azure-active-directory docker-swarm
docker nginx .net-core azure-active-directory docker-swarm
asked Mar 24 at 23:07
Mike UMike U
1,03851833
1,03851833
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55329449%2fad-login-failure-when-using-docker-and-multiple-replicas%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55329449%2fad-login-failure-when-using-docker-and-multiple-replicas%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown