I'm getting this
No web page was found for the web address: https://limbu.azurewebsites.net/
Everything worked fine in development but after publishing I get this error.
I can navigate to Views by typing in url but not the index page. I'm also not able to perform Register and login functions from controller in published website.
My Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Production")
{
services.Configure<IServiceProvider>(options => {
options.GetService<AppDbContext>().Database.Migrate();
}).AddDbContextPool<AppDbContext>(options => {
options.UseSqlServer(_config.GetConnectionString("AzureSqlConnection"));
//options.EnableSensitiveDataLogging(true);
});
}
else
{
services.AddDbContextPool<AppDbContext>(options => options.UseSqlServer(_config.GetConnectionString("Connection")));
}
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.SignIn.RequireConfirmedEmail = true;
}).AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
services.AddTransient<IMailService, SendGridMailService>();
services.AddHostedService<TimedHostedServices>();
services.AddScoped<IGetGlobalCovidData, GetGlobalCovidData>();
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
}).AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
//ServicePointManager.ServerCertificateValidationCallback += //This code is security risk as it validates all certificates
// (sender, certificate, chain, errors) => //Not to be used for production and used this instance as I trust the
// { //The site I'm pulling data from
// return errors == SslPolicyErrors.None;
// };
//services.AddLogging(loggingBuilder => { //This code is security risk as it displays all sensitive data
// loggingBuilder.AddConsole() //Not recommended for production
// .AddFilter(DbLoggerCategory.Database.Command.Name, LogLevel.Information);
// loggingBuilder.AddDebug();
//});
}
// 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.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapDefaultControllerRoute();
});
}
Please advise me on what I should provide for debugging.
my .cshtml build action is -content and donotcopy
.cs build action is -c# compiler and donotcopy
For the users who are getting the same issue, There could be different root causes for 404 error messages. Sub-status codes will help you understand the issue better.
You may check whether the site files are deployed correctly or not through Kudu Console. Also, suggest you Enable diagnostics logging for web apps in Azure App Service incase if you haven’t enabled earlier to check the complete error details and root cause.
Related
Are there an explicit "Access-Control-Allow-Credentials" attribute to explicitly allow credentials to be sent with a request to a specific client site?
I have tried the following
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://my-account-name.github.io",
"http://my-account-name.github.io/My-repository",
"https://my-account-name.github.io",
"https://my-account-name.github.io/My-repository");
});
});
...
app.UseCors(MyAllowSpecificOrigins);
Not working solution source
And I get the "CORS" policy restriction in Chrome console nevertheless for those request that include credential headers and / or authorize cookies. Other requests (that don't include credentials) are passing fine with cors fetch() from JS.
The complete solution to the CORS Cookie Authorization is the SameSite = None; cookie policy (which you have to tell the browser explicitly from your server)
// Controller.cs
[EnableCors("_allowSpecific")] // !!!
public class YourController : Controller
// ...
// Startup.cs (.Net 5) / Program.cs (.Net 6-7 +)
string MyAllowSpecificOrigins = "_allowSpecific";
public void ConfigureServices(IServiceCollection services)
{
services.AddSession(options =>
{
options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None; // !!!
});
services.AddCors(options => {
options.AddPolicy(name: MyAllowSpecificOrigins,
policy => { policy.WithOrigins( "http://your-domain.your-site.com", "https://your-domain.your-site.io", "http://your-domain.your-site.io"
#if DEBUG // Use this for debugging CORS in NPM on another localhost port
, "http://localhost:8081", "https://localhost:8081", "http://127.0.0.1:8081", "http://192.168.1.64:8081"
#endif
).AllowAnyHeader().AllowAnyMethod().AllowCredentials();
});
});
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; // !!!
});
// ADD your services, DbContexts, Identity, Configure<IdentityOptions>, AddDefaultIdentity<IdentityUser>, AddRoles<IdentityRole>, AddEntityFrameworkStores<ApplicationDbContext>, ConfigureApplicationCookie, AddDatabaseDeveloperPageExceptionFilter, AddSingleton<IHttpContextAccessor>, AddRazorPages, AddControllersWithViews, AddLogging,
services.ConfigureApplicationCookie(options => {
// Cookie settings
options.Cookie.SameSite = SameSiteMode.None; // !!!
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(10000);
options.SlidingExpiration = true;
});
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IWebHostEnvironment env, Microsoft.Extensions.Hosting.IHostApplicationLifetime appLifetime)
{
// ...
app.UseCookiePolicy(new CookiePolicyOptions {
MinimumSameSitePolicy = SameSiteMode.None // !!!
});
// app.UseRouting(); ...
app.UseCors(MyAllowSpecificOrigins); // ? 1) not sure whether you need to use both, but it works
app.UseAuthentication();
app.UseAuthorization();
app.UseCors(MyAllowSpecificOrigins); // ? 2) not sure if you need to use both, but it works
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}")
.RequireCors(MyAllowSpecificOrigins); // !!!
endpoints.MapRazorPages().RequireCors(MyAllowSpecificOrigins); // !!!
endpoints.MapControllers().RequireCors(MyAllowSpecificOrigins); // !!!
});
}
//...
Not only this setup will allow you to use CORS autherization (using cookie headers), this will also allow Chrome to block any request from other than "_allowSpecific" origins.
I had to spend almost a year to figure this out.
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 have done the session configuration for dotnet core 2.2 and still a new session is created with every request including Session.Id.
So I can't use the session as data holder.
I would like to use the session in connection with a ShoppingCart.
For this I created a separate API project, a separate Service project and a separate SPA project.
here is the ConfigureServices method
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper();
// DbContext using SQL Server Provider
services.AddDbContext<ICleanTasteDbContext, CleanTasteDbContext>(options =>
{
options.UseSqlServer(
Configuration.GetConnectionString("TasteConnection"),
m => m.MigrationsAssembly("Taste.Persistence")
);
});
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(30);
options.Cookie.IsEssential = true;
options.Cookie.HttpOnly = true;
});
services.AddHttpContextAccessor();
// custome services
services.AddTransient<ICartService<ICart>, CartService>();
// MVC
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// Cors
services.AddCors();
services.AddSpaStaticFiles(config =>
{
config.RootPath = "wwwroot";
});
}
and here is the Configure method
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseHsts();
}
app.UseCors(x =>
x.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin()
.AllowCredentials()
);
app.UseAuthentication();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "fallback", action = "index" }
);
});
app.UseSpa(spa =>
{
if (env.IsDevelopment())
{
spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
}
});
}
in the CartsController the service is called as follows
var cart = await cartService.Add(product);
in the CartService class IHttpContextAccessor is injected and called as follows
var cart = await httpContext.HttpContext.Session.Get<CartModel>(SESSION_NAME);
httpContext.HttpContext.Session.Set<CartModel>(SESSION_NAME, cart);
It is set correctly but with the next request there is a new instance of the session and is empty again.
What am I doing wrong?
Can it be related to the fact that I use different projects?
It's hard to say, but there's a couple of potential problems:
You're using in-memory sessions, which means you're process-bound. Sessions will never be shared between two different projects because each is a separate running process, with its own memory-backing. Additionally, when the app stops, anything stored in memory goes along with it, so if you stop and restart debugging, for example, or even just rebuild, your sessions go bye-bye. There is not true "distributed" memory cache. It's just an implementation of IDistributedCache that uses memory, but it's not really distributed.
Even if you had a truly distributed session store, each app by default carves out its own place in it, meaning it still won't be shared. You would need to ensure that both apps utilize a common data protection keyring location and that both apps have the same application name set.
I'm having some troubles setting up the correct Cors settings on my application.
NetCore application with Angular6 hosted on IIS, the angular app is outside the .Net project and compiled and inserted inside the wwwroot when publishing.
Now the problem is that when I'm coding the angular part, I'd like to call directly the release server to test some functionality.
I tried any kind of approach to have this work out but it seems like I'm always hitting a problem with the Cors setup but only for the POST calls, GET works fine. So here is my startup code:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ILoggerManager, LoggerManager>();
services.AddSingleton<IDbContext, MongoDbContext>();
services.AddSingleton<IIdGenerator, IdGenerator>();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
c.AddSecurityDefinition("Bearer", new ApiKeyScheme(){In = "header",Description = "Please enter JWT with Bearer into field", Name = "Authorization", Type = "apiKey"});
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
{
{"Bearer", Enumerable.Empty<string>()}
});
});
services.AddCustomRepositories();
services.AddCustomServices();
services.AddJwtService();
//Add cors
services.AddCors();
// Add framework services.
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.Configure<IISOptions>(options =>
{
options.ForwardClientCertificate = false;
});
services.Configure<Settings>(Configuration.GetSection("SystemSettings"));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//app.UseCors("AllowSpecificOrigin");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseCors(builder => builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod());
app.UseDefaultFiles();
// this will serve js, css, images etc.
app.UseStaticFiles();
app.Use(async (context, next) =>
{
if (context.Request.Path.HasValue &&
!context.Request.Path.Value.StartsWith("/api/") &&
!context.Request.Path.Value.StartsWith("/swagger"))
{
context.Response.ContentType = "text/html";
await context.Response.SendFileAsync(
env.ContentRootFileProvider.GetFileInfo("wwwroot/index.html")
);
return;
}
await next();
});
//app.UseHttpsRedirection();
app.UseSwagger();
app.UseAuthentication();
app.UseMiddleware(typeof(ErrorHandlingMiddleware));
app.UseMvc();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
c.DocExpansion(DocExpansion.None);
});
}
Since I want this enabled only for development purpose I'd like to enable it globally.
i think you need to set the origin manually
app.UseCors(builder =>
builder.AllowAnyOrigin().AllowAnyMethod());
as shown in here
This's the necessary part to add cors in your web API.
I created a sample project within VS 2017 using ASP.NET Core Templates 1.1 (Web Application) changing the authentication to be Individual User Accounts.
From there I followed the instructions at
https://learn.microsoft.com/en-us/aspnet/core/security/authentication/social/
and
https://auth0.com/docs/quickstart/webapp/aspnet-core/01-login
The Startup.cs is essentially
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddAuthentication(
options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
});
services.AddMvc(options=>
{
options.SslPort = 44321;
options.Filters.Add(new RequireHttpsAttribute());
});
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
services.AddOptions();
services.Configure<Auth0Settings>(Configuration.GetSection("Auth0"));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IOptions<Auth0Settings> auth0Settings)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseIdentity();
// Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true
});
var options = new OpenIdConnectOptions("Auth0")
{
Authority = $"https://{auth0Settings.Value.Domain}",
ClientId = auth0Settings.Value.ClientId,
ClientSecret = auth0Settings.Value.ClientSecret,
AutomaticAuthenticate = false,
AutomaticChallenge = false,
SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme,
ResponseType = "code",
CallbackPath = new PathString("/signin-auth0"),
// Configure the Claims Issuer to be Auth0
ClaimsIssuer = "Auth0",
};
options.Scope.Clear();
options.Scope.Add("openid");
app.UseOpenIdConnectAuthentication(options);
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
I register a user, navigate to manage your account and click, Manage link next to External Logins.
I click Auth0 button and successfully login. I get redirected to /Manage/LinkLoginCallback where the following method returns null.
private Task<ApplicationUser> GetCurrentUserAsync()
{
return _userManager.GetUserAsync(HttpContext.User);
}
Causing the following to appear
Error. An error occurred while processing your request. Development
Mode Swapping to Development environment will display more detailed
information about the error that occurred.
Development environment should not be enabled in deployed
applications, as it can result in sensitive information from
exceptions being displayed to end users. For local debugging,
development environment can be enabled by setting the
ASPNETCORE_ENVIRONMENT environment variable to Development, and
restarting the application.
I'm not sure what i'm doing wrong with respect to configuring Auth0 and Identity. In addition, if you know how to address the error above when the launchSettings.json does have ASPNETCORE_ENVIRONMENT as Development, that would also be much appreciated.