I added support in my Blazor Server app for downstream API in which I send an access token to the API. This caused the authentication against Azure AD to stop working, by giving me cookies that chrome refuses due to SameSite policy (it does authenticate, but can't save the cookie). It works fine from localhost, but not at all in Azure. The warning I get in Chrome is:
A cookie associated with a cross-site resource at https://---snip---.azurewebsites.net/ was set without the SameSite attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with SameSite=None and Secure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.
(from uri: https://login.microsoftonline.com/98f2d82c-c037-4c5f-a381-074c1428381c/reprocess?ctx=...)
The only code I can think of that would give me this issue is the following, which retrieves the access token, and handles the exception in Blazor. This code is from here:
https://github.com/AzureAD/microsoft-identity-web/wiki/Managing-incremental-consent-and-conditional-access
private async Task<string> GetAccessToken(string[] requiredScopes)
{
string[] scopes = requiredScopes ?? _configuration["DownstreamAPI:Scopes"]?.Split(' ');
string accessToken = null;
try
{
accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes);
}
catch (Exception ex)
{
_consentHandler.HandleException(ex);
}
return accessToken;
}
My Startup.cs:
using Blazored.Modal;
using Airline.CAM.WebUI.Utility;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using System.Net.Http;
using Microsoft.AspNetCore.Http;
namespace Airline.CAM.WebUI
{
public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
{
Configuration = configuration;
WebHostEnvironment = webHostEnvironment;
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment WebHostEnvironment { get; set; }
// 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<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.HandleSameSiteCookieCompatibility();
});
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters.RoleClaimType = "roles";
options.NonceCookie.SameSite = SameSiteMode.None;
});
var scopes = new[] { "api://---snip---/Cam_access_as_user" };
services.AddMicrosoftIdentityWebAppAuthentication(Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi(scopes)
.AddInMemoryTokenCaches();
services.AddMicrosoftGraph(scopes, "https://graph.microsoft.com/v1.0");
if (!WebHostEnvironment.IsDevelopment())
{
services.AddSignalR().AddAzureSignalR(options =>
{
options.ServerStickyMode = Microsoft.Azure.SignalR.ServerStickyMode.Required;
});
}
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
services.AddScoped<JsConsole>();
services.AddScoped<HttpClient>();
services.AddScoped<Utility.DownstreamWebApi>();
services.AddScoped<ApiHelper>();
services.AddRazorPages();
services.AddServerSideBlazor(o => o.DetailedErrors = true).AddMicrosoftIdentityConsentHandler();
services.AddBlazoredModal();
services.AddApplicationInsightsTelemetry(Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"]);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseExceptionHandler("/Error");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
}
Related
I have the following function to call users from active directory use graph api. This function is hit on each keyup of a text box. But i am getting following error
Code: TokenNotFound Message: User not found in token cache. Maybe the server was restarted.
in this line of code
var user = await graphClient.Users.Request().GetAsync();
My class
public class GraphSdkHelper : IGraphSdkHelper
{
private readonly IGraphAuthProvider _authProvider;
private GraphServiceClient _graphClient;
public GraphSdkHelper(IGraphAuthProvider authProvider)
{
_authProvider = authProvider;
}
// Get an authenticated Microsoft Graph Service client.
public GraphServiceClient GetAuthenticatedClient(ClaimsIdentity userIdentity)
{
_graphClient = new GraphServiceClient(new DelegateAuthenticationProvider(
async requestMessage =>
{
// Get user's id for token cache.
var identifier = userIdentity.FindFirst(Startup.ObjectIdentifierType)?.Value + "." + userIdentity.FindFirst(Startup.TenantIdType)?.Value;
// Passing tenant ID to the sample auth provider to use as a cache key
var accessToken = await _authProvider.GetUserAccessTokenAsync(identifier);
// Append the access token to the request
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
// This header identifies the sample in the Microsoft Graph service. If extracting this code for your project please remove.
requestMessage.Headers.Add("SampleID", "aspnetcore-connect-sample");
}));
return _graphClient;
}
}
public interface IGraphSdkHelper
{
GraphServiceClient GetAuthenticatedClient(ClaimsIdentity userIdentity);
}
}
Starup class
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public const string ObjectIdentifierType = "http://schemas.microsoft.com/identity/claims/objectidentifier";
public const string TenantIdType = "http://schemas.microsoft.com/identity/claims/tenantid";
// 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 =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
}).AddAzureAd(options => Configuration.Bind("AzureAd", options)).AddCookie();
services.AddControllersWithViews();
services.AddRazorPages();
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromSeconds(10);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
// Add application services.
//services.AddSingleton<IConfiguration>(Configuration);
services.AddSingleton<IGraphAuthProvider, GraphAuthProvider>();
services.AddTransient<IGraphSdkHelper, GraphSdkHelper>();
//Connection string
services.AddDbContext<PFEContext>(options => options.UseSqlServer(Configuration.GetConnectionString("PFEContext")));
//Group authorization
services.AddAuthorization(options => options.AddPolicy("Customer", policyBuider =>
policyBuider.RequireClaim("groups", "fb721f47-a58c-450a-9fbd-ff13f5960049")));
services.AddAuthorization(options => options.AddPolicy("Developper", policyBuider =>
policyBuider.RequireClaim("groups", "4fad5c4d-9bf9-477b-8814-02dffea5f102")));
services.AddAuthorization(options => options.AddPolicy("ProjectManager", policyBuider =>
policyBuider.RequireClaim("groups", "635b3fff-bb39-4726-8d76-1fef66fb2e8c")));
services.AddAuthorization(options => options.AddPolicy("Tester", policyBuider =>
policyBuider.RequireClaim("groups", "484d8c6c-f458-422f-9e0a-66a971874f3c")));
}
// 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("/Home/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.UseCookiePolicy();
app.UseSession();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
i need same help to fix this problem , what's going wrong ?
I think that is probably caused by the token that is not well persisting in memory cache,
Otherwise, maybe you are restarting your apps when you close the browser so you need to disable this option in VS because when you restarting the app it's clear all temporary data in memrory .
you can follow these steps disabling this feature:
Go into Tools -> Options, then navigate into Projects and Solutions -> Web Projects and uncheck the option Stop debugger when the browser window is closed.
I am trying to create a Web API in .NET core 3.1 however I am getting the following error -
"Unable to resolve service for type 'Swashbuckle.AspNetCore.Swagger.ISwaggerProvider' while attempting to Invoke middleware 'Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware'"
I am using .NET Core 3.1 & Swashbuckle.AspNetCore.SwaggerGen, Version=5.2.1.0
My Startup.cs is like:
using AutoMapper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder => builder
.WithOrigins(Configuration["AllowedHosts"])
.AllowAnyMethod()
.AllowAnyHeader());
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
// Load custom configuration related to error settings.
var errorConfig = new ConfigurationBuilder().AddJsonFile("errorSettings.json").Build();
// Load settings
services.AddOptions();
services.Configure<SecuritySettings>(Configuration.GetSection("SecuritySettings"));
services.Configure<ErrorSettings>(errorConfig.GetSection("ErrorSettings"));
// Load Database connection strings from AppSettings and load data context.
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyDbContext")));
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1", Description = "API" });
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
services.AddControllersWithViews()
.AddNewtonsoftJson(options => options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize);
// Configure mappers
var mapperConfig = new MapperConfiguration(opts =>
{
opts.AddProfile(new AutoMapperProfile());
});
var mapper = mapperConfig.CreateMapper();
services.AddSingleton<IMapper>(mapper);
// Add Http Context Accessor
services.AddHttpContextAccessor();
// Add Http client factory
services.AddHttpClient();
// Add transient for Services.
services.AddTransient<ICustomerService, CustomerService>();
services.AddTransient<IUserService, UserService>();
}
// 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.EnvironmentName == "Development")
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("../swagger/v1/swagger.json", "My API");
c.RoutePrefix = string.Empty;
});
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseCors("CorsPolicy");
}
}
}
I use .NET Core 3.1.200-preview-014977, Blazor, Swagger UI 5.0.0, my dependencies
I follow guide at https://learn.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-3.1&tabs=visual-studio . This is my config
using foo.Areas.Identity;
using foo.Controllers;
using foo.Data;
using Demo.Blazor;
using DevExpress.Blazor.DocumentMetadata;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using System.Globalization;
using System.Net.Http;
using Microsoft.OpenApi.Models;
using System;
namespace foo
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("vi-VN");
services.AddServerSideBlazor().AddCircuitOptions(options => { options.DetailedErrors = true; });
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>().AddRoles<IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages().AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
services.AddRazorPages().AddRazorPagesOptions(options =>
{
//options.Conventions.AuthorizePage("/currencies");
//options.Conventions.AuthorizeFolder("/accounts");
});
services.AddServerSideBlazor();
services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
services.AddSingleton<WeatherForecastService>();
services.AddDocumentMetadata((serviceProvider, registrator) =>
{
DemoConfiguration config = serviceProvider.GetService<IOptions<DemoConfiguration>>().Value;
config.RegisterPagesMetadata(registrator);
});
services.AddMvc();
services.AddHealthChecks();
services.AddHttpClient();
services.AddScoped<HttpClient>((sp) => {
var httpClient = sp.GetService<IHttpClientFactory>().CreateClient();
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
return httpClient;
});
services.AddDevExpressBlazor();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
//app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
endpoints.MapHealthChecks("/health");
});
}
}
}
I catch error:
Failed to load API definition.
How to fix it?
The issue may occur if one of your controller's is missing [Http*] attributes.
Consider the code below:
[Route("[action]")]
public async Task<IEnumerable<IdentityRole>> GetRoles()
{
_logger.LogDebug("Getting roles");
return await _roleManager.Roles.ToListAsync();
}
Your application will work, but Swagger wouldn't. Only because the example endpoint does not have [Http*] attribute defined, and thus, the swagger would fail to 'parse' your controller. Hence you see "Failed to load API definition." error message.
In this case, you would add [HttpGet] attribute like so:
[HttpGet]
[Route("[action]")]
public async Task<IEnumerable<IdentityRole>> GetRoles()
{
_logger.LogDebug("Getting roles");
return await _roleManager.Roles.ToListAsync();
}
Hope this help! This may not be an exact issue you are having, but the point is that if your controller's are not defined using common patterns, swagger will not be able to recognize them.
Good luck!
It should be like this
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("v1/swagger.json", "My API V1");
});
I create applications for internal use,
trying to get user login through IHttpContextAccessor
Controller:
private Microsoft.AspNetCore.Http.IHttpContextAccessor _httpContextAccessor;
var userName = _httpContextAccessor.HttpContext.User.Identity.Name;
//var userName = #"ad\LOGINUSER";
if I extract username using _httpContextAccessor.HttpContext.User.Identity.Name; mam błąd na stronie
Error.
An error occurred while processing your request.
Request ID: |77762974-42ec74070b648c99.
Development Mode
Swapping to Development environment will display more detailed information about the error that occurred.
if I use var userName = #"ad\LOGINUSER"; everything works normally
of course, the error is after publishing, everything works fine in normal compilation on computer
I'm using .net core 3.1
My startup code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using AppEcp.Models;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.Server.IISIntegration;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.AspNetCore.Mvc.Infrastructure;
namespace AppEcp
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc();
services
.AddHttpContextAccessor();
// services
// .TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();
services
.AddAuthentication(IISDefaults.AuthenticationScheme);
services
.AddControllersWithViews()
.AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
// .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
services.AddCors(c =>
{
c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
});
var connectionAd = #"Server=wsql3;Database=ActiveDirectory;Trusted_Connection=True;MultipleActiveResultSets=true";
services.AddDbContext<UzytkownicyDbContext>(options => options.UseSqlServer(connectionAd));
var connectionUrlop = #"Server=wsql3;Database=ECP;Trusted_Connection=True;MultipleActiveResultSets=true";
services.AddDbContext<EcpDbContext>(options => options.UseSqlServer(connectionUrlop));
}
// 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();
// app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// app.UseHsts();
}
// app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Ewidencja}/{id?}");
});
}
}
}
does anyone know what i have done wrong?
You didn't enable Authentication by UseAuthentication:
app.UseAuthentication(); // add this line
app.UseAuthorization();
Within a Controller, you don't have to access HttpContext by _httpContextAccessor.HttpContext...., you can get the User by HttpContext.User.
Also, it's your duty to check whether the User is null :
var user = HttpContext.User;
if(user ==null)
{
...
}else{
var userName = user.Identity.Name;
...
}
Finally, if above changes doesn't fix the problem, could you please show us the logs?
I am trying to get a net core 3.1 with identity setup with Razor pages where all pages require login and I want the login to last on the browser for 300 days.
I have tried updating my startup.cs file to so that the login will last for a long time. But no matter what I have tried the login will not last more than 20 or 30 minutes. Below is my current startup.cs file.
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using IKDataWeb.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Identity.UI.Services;
using IKDataWeb.Services;
namespace IKDataWeb
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection"),
sqlServerOptions => sqlServerOptions.CommandTimeout(900)
));
services.AddDefaultIdentity<IdentityUser>(options => {
options.SignIn.RequireConfirmedAccount = true;
options.Lockout.AllowedForNewUsers = true;
})
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.ConfigureApplicationCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(300);
options.SlidingExpiration = true;
});
services.AddRazorPages().AddRazorOptions(options =>
{
options.PageViewLocationFormats.Add("/Pages/Shared/Components/Master/{0}.cshtml");
});
services.AddControllers(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
services.AddSingleton<IEmailSender, EmailSender>();
services.AddSingleton<IEmailConfiguration>(Configuration.GetSection("EmailConfiguration").Get<EmailConfiguration>());
services.AddTransient<IEmailService, EmailService>();
services.AddTransient<IFilterProducts, FilterProducts>();
}
// 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();
app.UseDatabaseErrorPage();
}
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.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
}
Actually, it turns out that Rono was correct!
This answer did the trick.
Thanks for your help!