Right now I am developing asp net core 2.0 web site and I am adding authorization.
I have existing auth server build using identity server 4. I added new client with Implicit grant type. When I run locally I am successfully redirected to identity server and than after login back to we site. But when I deployed web site I am getting
An unhandled exception occurred while processing the request.
Exception: Correlation failed.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler+<HandleRequestAsync>d__12.MoveNext()
when redirected back after login. What can case the issue ?
Btw, here is my startup
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "oidc";
})
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.Cookie.Name = "mvcimplicit";
})
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://identity.************.com/";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc.client";
options.SaveTokens = true;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDeveloperExceptionPage();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
Do you have any ideas ?
May be you have some sort of cluster without exlicity defined data protection? Its potentially can produce behaviour like you describe.
Related
I have auth0 authentication implemented for my webAPIs. But now due to some requirement change few of APIs need to be authorized with another scheme. So I need below specified different authorization schemes to authorize my API
Auth0 scheme (already authorizing api's)
Azure AD B2C
I have implemented Azure AD B2C and which is working fine when used alone but when I am trying to add it enable it with a previous scheme it is causing issues.
public static IServiceCollection AddSecurityPolicy(this IServiceCollection services, ConfigurationManager config)
{
const string ClientPortalScheme = "ClientPortalBearerScheme";
//from https://auth0.com/blog/securing-aspnet-minimal-webapis-with-auth0/
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.Authority = config["AuthenticationSettings:Domain"];
options.Audience = config["AuthenticationSettings:Audience"];
}).AddJwtBearer(ClientPortalScheme, ClientPortalScheme, options =>
{
options.Authority = config["AzureADB2CSettings:Domain"];
options.Audience = config["AzureADB2CSettings:Tenant"];
});
//services.AddMicrosoftIdentityWebApiAuthentication(config, "AzureADB2CSettings");
//By default, require an authenticated user
//Only one JWT bearer authentication is registered with the default authentication scheme JwtBearerDefaults.AuthenticationScheme.
//Additional authentication has to be registered with a unique authentication scheme.
//see https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-6.0
services.AddAuthorization(options =>
{
var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
JwtBearerDefaults.AuthenticationScheme,
ClientPortalScheme);
defaultAuthorizationPolicyBuilder =
defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
});
return services;
}
This is how my code looks like.
Issue is when I am calling my endpoint it says
Unable to obtain configuration from: 'https://mydomain.auth0.com/.well-known/openid-configuration'.
---> System.IO.IOException: IDX20804: Unable to retrieve document from: 'https://mydomain.auth0.com/.well-known/openid-configuration'.
Please let me know if any information is required int this regard
I tried to reproduce the issue in my environment.
It occurs when app config is not receiving OpenIDmeta data properly
The issue was due to TLS configuration in my case as TLS 1.1 or TLS 1.0 are depreciated.
Please make sure to set TLS to 1.2 or greater.
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
IdentityModelEventSource.ShowPII = true;
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
......
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;;
....
app.UseAuthentication();
app.UseAuthorization();
....
}
Please make sure your backend API refers to /.well-known/openid-configuration
Or check this way.
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
MetadataAddress = "http[s]://{IdentityServer}/.well-known/openid-configuration"
...
});
In AzureAdB2c make sure to set the Authority or (Domain and instance ) property correctly .
Authority being the combination of Instance and domain
Appsettings.json
Authority : https://[yourb2ctenant}.b2clogin.com/{Configuration["AzureAdB2C:Tenant"]}/{Configuration["AzureAdB2C:Policy"]}/v2.0
Also see if Instance can be https://<tenant>.b2clogin.com/tfp/
Domain : <b2ctenant>.onmicrosoft.com
Then the authentication can be carried on successfully:
We have a .NET 5 (Blazor Server) app running in Azure Kubernetes that uses OpenID Connect to authenticate with a 3rd party. The app is running behind Ingress. Ingress uses https. The app is only http. After we authenticate with OIDC and get redirected back to /signin-oidc, we get a .NET error that we haven't been able to solve.
warn: Microsoft.AspNetCore.Http.ResponseCookies[1]
The cookie '.AspNetCore.OpenIdConnect.Nonce.CfDJ8EYehvsxFBVNtGDsitGDhE8K9FHQZVQwqqr1YO-zVntEtRgpfb_0cHpxfZp77AdGnS35iGRKYV54DTgx2O6ZO_3gq98pbP_XcbHnJmBDtZg2g5hhPakTrRirxDb-Qab0diaLMFKdmDrNTqGkVmqiGWpQkSxcnmxzVGGE0Cg_l930hk6TYgU0qmkzSO9WS16UBOYiub32GF4I9_qPwIiYlCq5dMTtUJaMxGlo8AdAqknxTzYz4UsrrPBi_RiWUKaF6heQitbOD4V-auHmdXQm4LE' has set 'SameSite=None' and must also set 'Secure'.
warn: Microsoft.AspNetCore.Http.ResponseCookies[1]
The cookie '.AspNetCore.Correlation.MMrYZ2WKyYiV4hMC6bhQbGZozpubcF2tYsKq748YH44' has set 'SameSite=None' and must also set 'Secure'.
warn: Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConnectHandler[15]
'.AspNetCore.Correlation.MMrYZ2WKyYiV4hMC6bhQbGZozpubcF2tYsKq748YH44' cookie not found.
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.Exception: An error was encountered while handling the remote login.
---> System.Exception: Correlation failed.
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.HandleRequestAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
public class Startup
{
private static readonly object refreshLock = new object();
private IConfiguration Configuration;
private readonly IWebHostEnvironment Env;
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Console.WriteLine($"LogQAApp Version: {Assembly.GetExecutingAssembly().GetName().Version}");
// We apparently need to set a CultureInfo or some of the Razor pages dealing with DateTimes, like LogErrorCountByTime fails with JavaScript errors.
// I wanted to set it to CultureInvariant, but that wouldn't take. Didn't complain, but wouldn't actually set it.
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
Configuration = configuration;
Env = env;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // Needed for 1252 code page encoding.
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("");
services.AddSignalR(e =>
{
e.MaximumReceiveMessageSize = 102400000;
});
services.AddBlazoredSessionStorage();
services.AddCors();
services.AddSyncfusionBlazor();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddHttpContextAccessor();
ServiceConfigurations.LoadFromConfiguration(Configuration);
#region Authentication
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(
options =>
{
options.Events = GetCookieAuthenticationEvents();
}
)
.AddOpenIdConnect("SlbOIDC", options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = Configuration["SlbOIDC:Authority"];
if (Env.IsDevelopment())
{
options.ClientId = Configuration["SlbOIDC:ClientID"];
options.ClientSecret = Configuration["SlbOIDC:ClientSecret"];
}
else
{
options.ClientId = Configuration.GetValue<string>("slbclientid");
options.ClientSecret = Configuration.GetValue<string>("slbclientsecret");
}
options.ResponseType = OpenIdConnectResponseType.Code;
options.UsePkce = true;
options.SaveTokens = true;
options.ClaimsIssuer = "SlbOIDC";
// Azure is communicating to us over http, but we need to tell SLB to respond back to us on https.
options.Events = new OpenIdConnectEvents()
{
OnRedirectToIdentityProvider = context =>
{
Console.WriteLine($"Before: {context.ProtocolMessage.RedirectUri}");
context.ProtocolMessage.RedirectUri = context.ProtocolMessage.RedirectUri.Replace("http://", "https://");
Console.WriteLine($"After: {context.ProtocolMessage.RedirectUri}");
return Task.FromResult(0);
}
};
});
services.AddSession(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
options.Cookie.IsEssential = true;
});
#endregion
services.AddScoped<BrowserService>();
services.AddSingleton<ConcurrentSessionStatesSingleton>();
services.AddSingleton<URLConfiguration>();
services.AddScoped<CircuitHandler>((sp) => new CircuitHandlerScoped(sp.GetRequiredService<ConcurrentSessionStatesSingleton>(), sp.GetRequiredService<BrowserService>(), sp.GetRequiredService<IJSRuntime>()));
services.AddScoped<SessionServiceScoped>();
services.AddScoped<LogEditorScoped>();
services.AddSingleton<ModalService>();
services.AddFlexor();
services.AddScoped<ResizeListener>();
services.AddScoped<ApplicationLogSingleton>();
services.AddScoped<LogChartsSingleton>();
services.AddScoped<CurveNameClassificationSingleton>();
services.AddScoped<HubClientSingleton>();
services.AddScoped((sp) => new LogAquisitionScopedService(
sp.GetRequiredService<URLConfiguration>(),
sp.GetRequiredService<HubClientSingleton>(),
sp.GetRequiredService<ApplicationLogSingleton>(),
sp.GetRequiredService<IConfiguration>(),
sp.GetRequiredService<SessionServiceScoped>(),
sp.GetRequiredService<AuthenticationStateProvider>(),
sp.GetRequiredService<IHttpContextAccessor>(),
sp.GetRequiredService<IJSRuntime>()
)
);
services.AddScoped<UnitSingleton>();
services.AddServerSideBlazor().AddCircuitOptions(options => { options.DetailedErrors = true; });
services.AddScoped<TimeZoneService>();
services.AddHostedService<ExcelBackgroundService>();
services.AddHostedService<LogEditorBackgroundService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
//app.UseHsts();
}
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseCookiePolicy();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthentication();
if (!Env.IsDevelopment())
{
app.UseTrafficManager();
}
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
private CookieAuthenticationEvents GetCookieAuthenticationEvents()
{
return new CookieAuthenticationEvents()
{
OnValidatePrincipal = context =>
{
lock (refreshLock)
{
if (context.Properties.Items.ContainsKey(".Token.expires_at"))
{
DateTime expire = DateTime.Parse(context.Properties.Items[".Token.expires_at"]);
if (expire.AddMinutes(-20) < DateTime.Now)
{
try
{
CloudAuthentication cloudAuthentication = new CloudAuthentication();
TokenResponse tokenResponse = cloudAuthentication.GetRefreshToken(context.Properties.Items[".Token.refresh_token"]);
context.Properties.Items[".Token.access_token"] = tokenResponse.access_token;
context.Properties.Items[".Token.refresh_token"] = tokenResponse.refresh_token;
context.Properties.Items[".Token.expires_at"] = DateTime.Now.AddSeconds(tokenResponse.expires_in).ToString();
context.ShouldRenew = true;
}
catch (Exception ex)
{
context.RejectPrincipal();
}
}
}
return Task.FromResult(0);
}
}
};
}
}
It's a good question - there are a couple of interesting points here that I've expanded on since they are related to SameSite cookies.
REVERSE PROXY SETUP
By default the Microsoft stack requires you to run on HTTPS if using cookies that require an SSL connection. However, you are providing SSL via a Kubernetes ingress, which is a form of reverse proxy.
The Microsoft .Net Core Reverse Proxy Docs may provide a solution. The doc suggests that you can inform the runtime that there is an SSL context, even though you are listening on HTTP:
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});
I would be surprised if Microsoft did not support your setup, since it is a pretty mainstream hosting option. If this does not work then you can try:
Further searching around Blazor and 'reverse proxy hosting'
Worst case you may have to use SSL inside the cluster for this particular component, as Johan indicates
WIDER INFO - API DRIVEN OAUTH
Many companies want to develop Single Page Apps, but use a website based back end in order to manage the OAuth security. Combining serving of web content with OAuth security adds complexity. It is often not understood that the OAuth SPA security works better if developed in an API driven manner.
The below resources show how the SPA code can be simplified and in this example the API will issue cookies however it is configured. This would enable it to listen over HTTP inside the cluster (if needed) but to also issue secure cookies:
API driven OpenID Connect code
Curity Blog Post
WIDER INFO: SAMESITE COOKIES
It is recommended to use SameSite=strict as the most secure option, rather than SameSite=none. There are sometimes usability problems with the strict option however, which can cause cookies to be dropped after redirects or navigation from email links.
This can result in companies downgrading their web security to a less secure SameSite option. These problems do not occur when an API driven solution is used, and you can then use the strongest SameSite=strict option.
I installed AWS Toolkit for Visual Studio 2019 & created new "AWS Serverless Application(.NET Core C#)" project.
Following this video tutorial I configured new Cognito User Pool & edited the default project's Startup.cs & added secure page with [Authorize] attribute (at the 12min mark you can find the exact steps of how Cognito was configured).
After publishing to AWS (or even when debugging locally) when I navigate to secure page I correctly get redirected and prompted to login, but after successful login it enters a loop in the background that keeps sending back to OIDC authorization link & back to my site... after a few of those it throws an error of "ERR_TOO_MANY_REDIRECTS".
Any idea what is missing from this tutorial in order to make it work properly? The only step I skipped was that he registered a domain name for his site, while I'm just using the default site URL I get after right-clicking project & choosing "Publish to AWS Lambda".
Here's edited code of my Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
string clientId = "<cognito_app_client_id>";
string clientSecret = "<cognito_app_client_secret>";
string logoutUrl = "https://<published_app_aws_url>/logout";
string baseUrl = "https://<published_app_aws_url>";
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.ResponseType = OpenIdConnectResponseType.Code;
options.MetadataAddress = $"https://cognito-idp.<aws_region>.amazonaws.com/<cognito_pool_id>/.well-known/openid-configuration";
options.ClientId = clientId;
options.ClientSecret = clientSecret;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("email");
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProviderForSignOut = (context) =>
{
var logoutUri = logoutUrl;
logoutUri += $"client_id={clientId}&logout_uri={baseUrl}";
context.Response.Redirect(logoutUri);
context.HandleResponse();
return Task.CompletedTask;
}
};
});
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
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.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Thanks to comment by Philip Pittle I found the UseAuthentication must come before UseAuthorization.
I've been trying to set up Discord Oauth2 token authentication on an ASP.NET Core 2.2 / Angular 7 project and it has been quite a bumpy ride.
I'm using this
I really can't seem to find any examples that give more than a fraction of the explanation required to set this all up. The error I'm currently battling with is the following:
Access to XMLHttpRequest at 'https://discordapp.com/oauth2/authorize?client_id=<removed>&scope=identify&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Fsignin-discord&state=<removed>'
(redirected from 'http://localhost:5000/api/v1/Authentication/SignIn') from origin 'http://localhost:5000' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
For context, here is some of my code:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AllowAll",
builder => builder.WithOrigins("http://localhost:5000").AllowAnyHeader());
});
...
services.AddAuthentication(options =>
{
options.DefaultScheme = DiscordAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = DiscordAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(options =>
{
options.LoginPath = "/login";
options.LogoutPath = "/signout";
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
options.SlidingExpiration = true;
})
.AddDiscord(options =>
{
options.ClientId = "<removed>";
options.ClientSecret = "<removed>";
options.Scope.Add("identify");
});
...
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseCors("AllowAll");
...
}
// in AuthenticationController.cs
public class AuthenticationController : Controller
{
[HttpPost("[action]")]
public IActionResult SignIn()
{
return Challenge(new AuthenticationProperties {RedirectUri = "http://localhost:5000"});
}
...
}
What i've been trying
I tried following this
I tried all of these combinations of services.addCors() and app.UseCors() to no avail
services.AddCors();
app.UseCors(builder =>
builder.WithOrigins("http://localhost:5000").AllowAnyHeader());
services.AddCors();
app.UseCors(builder =>
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
and everything inbetween. The error does not change no matter what I do with cors. Also, yes I have the Microsoft.AspNetCore.Cors nu-get package installed. Yes, app.UseCors() is called before app.useMvc
Any other ideas?
I experienced a similar issue today but figured it out later. Make sure you are using the same versions of net core. I happened to be using both 2.1 and 2.2 packages.
I am trying to authenticate .net core 2.0 application with the Azure ad. I got it successful with authentication. But I need to session timeout after idle time.
Please find my startup.cs config
Configure
logger.AddConsole(Configuration.GetSection("Logging"));
logger.AddDebug((category, logLevel) => (logLevel >= LogLevel.Trace));
app.UseResponseCaching();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseSession();
app.UseAuthentication();
ConfigureServices
services.AddAuthentication(options =>
{
options.DefaultScheme= CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddOpenIdConnect(options =>
{
options.ClientId = Configuration["Authentication:AzureAd:ClientId"];
options.Authority = Configuration["Authentication:AzureAd:AADInstance"] + Configuration["Authentication:AzureAd:TenantId"];
options.ClientSecret = Configuration["Authentication:ClientSecret"];
options.CallbackPath = Configuration["Authentication:AzureAd:CallbackPath"];
options.ResponseType = OpenIdConnectResponseType.IdToken;
})
.AddCookie();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(1);
options.CookieHttpOnly = true;
});
As the section Implementation Details under Working with Session State states as follows:
The server uses the IdleTimeout property to determine how long a session can be idle before its contents are abandoned. This property is independent of the cookie expiration. Each request that passes through the Session middleware (read from or written to) resets the timeout.
I enabled the session state, then set session values in an action and read them in another action. Per my test, your configuration for AddSession would issue a cookie with the default name .AspNetCore.Session and contains the session ID to the browser. The IdleTimeout is 1 minute and if you read or update the session values, then the IdleTimeout would be reset.
UPDATE:
AFAIK, there is no SessionEvents under SessionOptions when using services.AddSession. Per my understanding, you could set the Cookie expire time when using cookie auth, then add the processing to remove the session values and send the sign-out request to AAD when the cookie is invalid. Here is my configuration, you could refer to it as follows:
public void ConfigureServices(IServiceCollection services)
{
// Add MVC services to the services container.
services.AddMvc();
// Add Authentication services.
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
// Configure the OWIN pipeline to use OpenID Connect auth.
.AddOpenIdConnect(option =>
{
option.ClientId = Configuration["AzureAD:ClientId"];
option.Authority = String.Format(Configuration["AzureAd:AadInstance"], Configuration["AzureAd:Tenant"]);
option.SignedOutRedirectUri = Configuration["AzureAd:PostLogoutRedirectUri"];
option.Events = new OpenIdConnectEvents
{
OnRemoteFailure = OnAuthenticationFailed,
};
})// Configure the OWIN pipeline to use cookie auth.
.AddCookie(op => {
op.ExpireTimeSpan = TimeSpan.FromMinutes(20);
op.LoginPath = "/Account/Login";
op.Events.OnRedirectToLogin =async(context) =>
{
//Clean the session values
context.HttpContext.Session.Clear();
//Sign-out to AAD
await context.HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
//Redirect to op.LoginPath ("/Account/Login") for logging again
context.Response.Redirect(context.RedirectUri);
};
});
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(20);
options.CookieHttpOnly = true;
});
}