I am using ASP.Net boilerplate architecture for my project and using Ocelot API Gateway.
Without using gateway, I can access signalr successfully from my angular App.
But when I try to access signalr through API Gateway, All requests stay in pending state and get this error
Following is my configuration.json changes for signalr
And following change I made in the Startup.cs file of the gateway.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
if (_ocelotSwaggerConfiguration.IsSwaggerEnabled)
{
app.UseSwaggerForOcelotUI(Configuration);
}
// Enable ReDoc Documentation
app.UseReDoc(c =>
{
c.DocumentTitle = "AI API";
c.SpecUrl = "/swagger/docs/v1/pitch-ai";
c.RoutePrefix = string.Empty;
c.IndexStream = () => Assembly.GetExecutingAssembly()
.GetManifestResourceStream("AI.Api.Gateway.api_docs.ui.index.html");
c.HeadContent = GetRedocHeaderContent();
});
app.UseAuthentication();
app.UseStaticFiles();
app.UseMetricServer();
app.UseMiddleware<ResponseMetricMiddleware>();
app.UseHttpMetrics();
app.UseWebSockets();
app.UseHealthChecks("/ready", new HealthCheckOptions
{
Predicate = r => r.Tags.Contains("services")
});
app.Map("/switch", appBuilder =>
{
appBuilder.Run(async context =>
{
running = !running;
await context.Response.WriteAsync($"{Environment.MachineName} running {running}");
});
});
app.UseHealthChecks("/health", new HealthCheckOptions
{
Predicate = r => r.Name.Contains("health")
});
app.UseMetricsAllEndpoints();
app.UseOcelot().ContinueWith(t => Log.Error(t.Exception.Message, t.Exception), System.Threading.Tasks.TaskContinuationOptions.OnlyOnFaulted);
}
The following change works for me. Applied following changes in configuration.json
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "ws",
"UpstreamPathTemplate": "/{everything}",
"UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ],
"SwaggerKey": "ai",
"ServiceName": "ai-web-api",
"RateLimitOptions": {
"ClientWhitelist": [],
"EnableRateLimiting": true,
"Period": "1s",
"PeriodTimespan": 1,
"Limit": 10
}
}
Also, I found that I don't need Microsoft.AspNetCore.SignalR.Client in gateway project.
And I moved app.UseWebSockets(); before app.UseOcelot() in Startup.cs
Related
I have deployed two services in kubernetes (bare-metal k0s. To do some tracing on Jaeger Service A makes a call to Service B for a JWT authentication token - this works perfectly when I test in Visual Studio (Service A is able to retrieve token from Service B).
However when I execute the call in Postman now that I have deployed to k0S , I cannot see neither the services or any traces Jaeger UI :
Using guide from here I have configured the services as below :
Service A (Startup.cs)
public class Startup
{
private readonly IWebHostEnvironment _environment;
public Startup(IConfiguration configuration, IWebHostEnvironment environment)
{
Configuration = configuration;
_environment = environment;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<ModelContext>(o => o.UseOracle(Configuration.GetConnectionString("OracleConn")));
services.AddCors(c =>
{
c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
});
services.AddTransient<IAsyncAccountService<SttmCustAccount>, AccountService>();
services.AddTransient<IAsyncLookupResponse, LookupService>();
services.AddOpenTracing();
services.AddSingleton<ITracer>(cli =>
{
var serviceName = cli.GetRequiredService<IWebHostEnvironment>().ApplicationName;
Environment.SetEnvironmentVariable("JAEGER_SERVICE_NAME", serviceName);
if (_environment.IsDevelopment())
{
Environment.SetEnvironmentVariable("JAEGER_AGENT_HOST", "localhost");
Environment.SetEnvironmentVariable("JAEGER_AGENT_PORT", "6831");
Environment.SetEnvironmentVariable("JAEGER_SAMPLER_TYPE", "const");
}
ILoggerFactory loggerFactory = cli.GetRequiredService<ILoggerFactory>();
ISampler sampler = new ConstSampler(sample: true);
ITracer tracer = new Tracer.Builder(serviceName)
.WithLoggerFactory(loggerFactory)
.WithSampler(sampler)
.Build();
GlobalTracer.Register(tracer);
return tracer;
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
Service B has the exact same configuration.
Jaeger operator is set up using NodePort with config as in this file :
[file][https://drive.google.com/file/d/1nAjQ2jHrLSZLWoV9vGb3l4b0M1_yTMTw/view?usp=sharing]
I have to tried to expose the operator as Traefik Ingress but failed and had to change to NodePort (Can this affect registering of services , if at all ?) :
This is the call in Service A that retrieves token from Service B :
[HttpGet]
public async Task<IActionResult> GetAccountAsync([FromQuery] AccountLookupRequest request)
{
string authenticationResponse = await GetTokenAsync();
if (authenticationResponse != null)
{
_logger.LogInformation("Called AccountLookup API");
List<AccountLookupResponse> res = new List<AccountLookupResponse>();
var tranRef = String.Format("{1}{2}{0}", Helpers.aa, Helpers.bb, DateTime.Now.ToString("yyMMddHHmmss"));
...
}
}
static async Task<string> GetTokenAsync()
{
var payload = "{\"Username\": \"golide\",\"Password\": \"It#XXXXX\"}";
Uri uri = new Uri("http://10.XXX.XXX.XXX:31306/users/authenticate");
HttpContent c = new StringContent(payload, Encoding.UTF8, "application/json");
AuthenticationResponse responseEntity = new AuthenticationResponse();
var response = string.Empty;
using (var client = new HttpClient())
{
HttpResponseMessage result = await client.PostAsync(uri, c);
if (result.IsSuccessStatusCode)
{
response = result.StatusCode.ToString();
// responseEntity = JsonConvert.DeserializeObject<AuthenticationResponse>(response);
}
}
return response;
}
In Postman context the call to http://10.170.XXX.XXX:30488/account?field4=3025202645050&field7=GENERIC01&field10=ABC076 will implicitly invoke the AuthenticationAPI at http://10.170.xxx.xxx:31306/users/authenticate
UPDATE
Container logs show that trace-id and span-id are being generated :
[02:54:03 INF] Executed action method
FlexToEcocash.Controllers.AccountController.GetAccountAsync (FlexToEcocash), returned result Microsoft.AspNetCore.Mvc.OkObjectResult in 416.2876ms.
[02:54:03 WRN] Event-Exception: Microsoft.AspNetCore.Mvc.BeforeActionResult
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Object.GetType()
at OpenTracing.Contrib.NetCore.AspNetCore.MvcEventProcessor.ProcessEvent(String eventName, Object arg)
at OpenTracing.Contrib.NetCore.AspNetCore.AspNetCoreDiagnostics.OnNext(String eventName, Object untypedArg)
at OpenTracing.Contrib.NetCore.Internal.DiagnosticListenerObserver.System.IObserver<System.Collections.Generic.KeyValuePair<System.String,System.Object>>.OnNext(KeyValuePair`2 value)
[02:54:03 INF] Executing ObjectResult, writing value of type 'FlexToEcocash.Models.ResponseModels.AccountLookupResponse'.
[02:54:03 INF] Executed action FlexToEcocash.Controllers.AccountController.GetAccountAsync (FlexToEcocash) in 421.8383ms
[02:54:03 WRN] Span has already been finished; will not be reported again. Operation: HTTP GET Trace Id: c976e25bf21bfae5 Span Id: c976e25bf21bfae5
[02:54:03 INF] Executed endpoint 'FlexToEcocash.Controllers.AccountController.GetAccountAsync (FlexToEcocash)'
[02:54:03 INF] Request finished in 426.0567ms 200 application/json; charset=utf-8
[02:54:03 WRN] Span has already been finished; will not be reported again. Operation: HTTP GET Trace Id: c976e25bf21bfae5 Span Id: c976e25bf21bfae5
What am I missing ?
I'm creating a web application in Blazor ASP.NET Core web hosted with ASP.NET Core 6 and when I'm migrating the database I'm getting this error:
Unable to create an object of type 'ApplicationDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
I need to get a solution - this is my code:
Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("Prueba")));
builder.Services.AddDefaultIdentity<ApplicationUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["JwtIssuer"],
ValidAudience = builder.Configuration["JwtAudience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JwtSecurityKey"]))
};
});
builder.Services.AddAuthorization(config =>
{
config.AddPolicy(Policies.IsAdmin, Policies.IsAdminPolicy());
config.AddPolicy(Policies.IsUser, Policies.IsUserPolicy());
});
builder.Services.AddSignalR();
builder.Services.AddMvc().AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
builder.Services.AddControllersWithViews();
//builder.Services.AddRazorPages();
builder.Services.AddResponseCompression(option =>
{
option.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat
(new[] { "application/octet-stream"
});
});
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
SeedData.Initialize(services);
}
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllers();
app.MapFallbackToFile("index.html");
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<UsuariosHub>("/UsuariosHub");
});
app.Run();
ApplicationDbContext.cs
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using ProyectoBP.Shared.Models;
namespace ProyectoBP.Server.Data;
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
public DbSet<Movie> Movies { get; set; }
}
SeedData.cs
using Microsoft.EntityFrameworkCore;
using ProyectoBP.Server.Data;
namespace ProyectoBP.Shared.Models
{
public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var context = new ApplicationDbContext(
serviceProvider.GetRequiredService<
DbContextOptions<ApplicationDbContext>>()))
{
context.SaveChanges();
if (context == null || context.Movies == null)
{
throw new ArgumentNullException("Null ApplicationDbContext");
}
// Look for any movies.
if (context.Movies.Any())
{
return; // DB has been seeded
}
context.SaveChanges();
}
}
}
}
appsettings.json
{
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Data Source=ISMAEL-PC;Initial Catalog=BP;Integrated Security=False;uid=JoseD;password=Laugama2021.",
"Prueba": "Data Source=ISMAEL-PC;Initial Catalog=BP;Integrated Security=true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
I don't have a StartUp Class because apparently in ASP.NET Core 6 it's not needed
Add parameterless constructor on your DbContext (ApplicationDbContext.cs)
public ApplicationDbContext ()
{
}
Make sure you set the default startup project to the WebApplication
or add -s {Satrtup project name here} at end of the update command
Add Microsoft.EntityFrameworkCore.Design package to the WebApplication project
I solved my problem by checking the include prerelease option since I'm using ASP.NET Core 6 in a prerelease version but I was trying to migrate with the current stable version. So I hope this can help you.
You should replace
serviceProvider.GetRequiredService<DbContextOptions<ApplicationDbContext>>()
to
serviceProvider.GetRequiredService<ApplicationDbContext>()
in SeedData class :
using Microsoft.EntityFrameworkCore;
using ProyectoBP.Server.Data;
namespace ProyectoBP.Shared.Models
{
public static class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var context = serviceProvider.GetRequiredService<ApplicationDbContext>())
{
context.SaveChanges();
if (context == null || context.Movies == null)
{
throw new ArgumentNullException("Null ApplicationDbContext");
}
// Look for any movies.
if (context.Movies.Any())
{
return; // DB has been seeded
}
context.SaveChanges();
}
}
}
}
Temporary re-register all services from AddSingleton and AddScoped to AddTransient. It Worked for me.
I'm trying to use Authorization in .Net Framework 4.8, but making a get request returns Unauthorized using OpenIdentity4
I have to use Framework and not Core!
This is my Startup.cs:
public void Configuration(IAppBuilder app)
{
var authority = "https://localhost:5001";
var configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(
authority + "/.well-known/openid-configuration",
new OpenIdConnectConfigurationRetriever(),
new HttpDocumentRetriever());
var discoveryDocument = Task.Run(() => configurationManager.GetConfigurationAsync()).GetAwaiter().GetResult();
System.Console.WriteLine(discoveryDocument.AuthorizationEndpoint);
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
TokenValidationParameters = new TokenValidationParameters()
{
ValidateAudience = false,
}
}) ;
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "RestAPI",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
config.Formatters.JsonFormatter.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
app.UseWebApi(config);
}
}
}
OpenIdentity4 is running on https://localhost:5001
It's Startup:
public class Startup
{
public IWebHostEnvironment Environment { get; }
public Startup(IWebHostEnvironment environment)
{
Environment = environment;
}
public void ConfigureServices(IServiceCollection services)
{
var builder = services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryApiScopes(Config.ApiScopes)
.AddInMemoryClients(Config.Clients);
services.AddControllers();
services.AddAuthorization(options =>
{
options.AddPolicy("ApiScope", policy => {
policy.RequireAuthenticatedUser();
policy.RequireClaim("RestAPI", "APIRest");
});
});
}
public void Configure(IApplicationBuilder app)
{
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// uncomment if you want to add MVC
//app.UseStaticFiles();
//app.UseRouting();
app.UseIdentityServer();
app.UseRouting();
// uncomment, if you want to add MVC
app.UseAuthorization();
//app.UseEndpoints(endpoints =>
//{
// endpoints.MapDefaultControllerRoute();
//});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers()
.RequireAuthorization("ApiScope");
});
}
}
}
It's probably a stupid mistake, but I can't figure it out.
I am using nuget Microsoft.Extensions.Configuration.AzureKeyVault and I am using below code for asp.net core 3.1 in Program.cs,
I am doing custom certificate authentication for azure keyVault. Also using custom secret management.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
config.AddAzureKeyVault(new AzureKeyVaultConfigurationOptions
{
Vault = "key vault url",
ReloadInterval = TimeSpan.FromSeconds(15),
//authenticate with custom certificate
Client = new KeyVaultClient(CustomCertificateAuthenticationCallback),
Manager = new CustomKeyVaultSecretManager()
});
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
The package Microsoft.Extensions.Configuration.AzureKeyVault is deprecated and I have uninstalled this package and installed the updated one Azure.Extensions.AspNetCore.Configuration.Secrets. After switching to this package I am NOT able to figure our how to use custom validation and how to pass keyvault url
You could try SecretClient method, and refer to this official document about Azure Key Vault Configuration Provider.
using Azure.Security.KeyVault.Secrets;
using Azure.Identity;
using Azure.Extensions.AspNetCore.Configuration.Secrets;
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
if (context.HostingEnvironment.IsProduction())
{
var builtConfig = config.Build();
var secretClient = new SecretClient(new Uri($"https://{builtConfig["KeyVaultName"]}.vault.azure.net/"),
new DefaultAzureCredential());
config.AddAzureKeyVault(secretClient, new KeyVaultSecretManager());
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
SecretClient doesn't support AuthenticationCallback(Microsoft.Azure.KeyVault.KeyVaultClient.AuthenticationCallback).
If you would like to authenticate with certificate, you could new TokenCredential with Azure.Identity.ClientCertificateCredential.
X509Certificate2 cer = new X509Certificate2(certPath, pfxpassword, X509KeyStorageFlags.EphemeralKeySet);
var secretClient = new SecretClient(new Uri($"https://{builtConfig["KeyVaultName"]}.vault.azure.net/"),
new ClientCertificateCredential(tenantID, clientID, cer);
As the suggestion in the Accepted Answer does not have the ReloadInterval property, here is the suggestion to keep all properties as in the original code, while using the new package:
using Azure.Security.KeyVault.Secrets;
using Azure.Identity;
using Azure.Extensions.AspNetCore.Configuration.Secrets;
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
if (context.HostingEnvironment.IsProduction())
{
var builtConfig = config.Build();
config.AddAzureKeyVault(
new Uri($"https://{builtConfig["KeyVaultName"]}.vault.azure.net/"),
new DefaultAzureCredential(),
new AzureKeyVaultConfigurationOptions()
{
Manager = new KeyVaultSecretManager(),
ReloadInterval = TimeSpan.FromSeconds(15)
}
);
}
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
While logging into ADFS(on Premise), I am being redirected after I enter in my credentials and eventually it erros out with the error Exception details: Microsoft.IdentityServer.Web.InvalidRequestException: MSIS7042: The same client browser session has made '6' requests in the last '7' seconds. Contact your administrator for details in Event Viewer. I followed couple of stack overflow suggestion(link) but couldn't resolve the issue. I am running on https and made sure the certificate are right.
Here is my code
namespace TestApp
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
private static string HtmlEncode(string content) =>
string.IsNullOrEmpty(content) ? string.Empty : HtmlEncoder.Default.Encode(content);
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
options.Secure = CookieSecurePolicy.SameAsRequest;
});
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
options =>
{
options.Cookie.Name = ".AspNet.SharedCookie";
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Cookie.SameSite = SameSiteMode.None;
})
.AddWsFederation(options =>
{
options.MetadataAddress =
$"https://adfsdomain/FederationMetadata/2007-06/FederationMetadata.xml";
options.Wtrealm = "urn:apptest";
options.Wreply = "https://appdomain/apptest";
options.CallbackPath = "/apptest";
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = "https://adfsdomain/adfs/services/trust/"
};
options.SaveTokens = true;
options.RequireHttpsMetadata = false;
});
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddMvc();//.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseCors(policy => policy.SetIsOriginAllowed(origin => origin == "https://adfsdomain"));
app.UseHttpsRedirection();
app.UseStaticFiles();
app.Use(async (context, next) =>
{
if (!context.User.Identity.IsAuthenticated)
{
await context.ChallengeAsync(WsFederationDefaults.AuthenticationScheme);
}
else
{
await next();
}
});
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
I am using .Net Core 2.1 and ADFS 3.0. If I take ASP.NET MVC app and publish it with the same adfs setting my code works like charm, which tells me that the configuration on ADFS has been configured correctly.
Not sure if this can help you guys but I got my ADFS to working with the following:
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
})
.AddWsFederation(options =>
{
options.Wtrealm = this._Configuration["wsfed:realm"];
options.MetadataAddress = string.Format("{0}/federationmetadata/2007-06/federationmetadata.xml", this._Configuration["wsfed:metadata"]);
})
.AddCookie();
You need app.UseAuthorization() before the app.Use(async ...). That's the middleware that takes the headers from the redirect and populates the context.User.