Asp Net Core authentication troubles - c#

I have made asp net core web app with Angular. It is using authentication based on cookies using standard net core authentication mechanism. All is working fine until IIS restart (recycle). After application restarted all users becomes unauthenticated and needs to relogin.
May be some one knows what should be done to make information stored in cookies be actual for several days and not depending on application restart.
This is the piece of code
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyAppContext>(options => options.UseMySql(connectionString));
services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
{
options.User.RequireUniqueEmail = true;
options.SignIn.RequireConfirmedEmail = true;
})
.AddEntityFrameworkStores<MyAppContext>()
.AddDefaultTokenProviders();
services.AddAuthorization();
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.SlidingExpiration = true;
options.ExpireTimeSpan = System.TimeSpan.FromDays(7);
options.LoginPath = $"/Identity/Login";
options.LogoutPath = $"/Identity/Logout";
options.Cookie.IsEssential = true;
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
}

Asp.Net Core uses the Data Protection mechanism to generate temporary encryption keys. and with the restart of the server or IIS, these keys are lost and re-generated.
In order that the keys for encrypting web application information are stored permanently and not lost with the server restart you can go to Application pool setting in IIS and set Load user profile to True
In this case, the keys will be permanently stored in the user's profile folder for the application's application pool, encrypted by the Windows DPAPI mechanism.
Or you can check these links 1,2 to keep the login status after iis reset

Related

.Net Core Identity AuthenticationCookie not working

I recently ran into a problem with my net5.0 application (upgraded from net core 3.1). I am using Microsoft.AspNetCore.Identity to sign in and it works perfectly fine. After deploying it to the production machine the login is still working and I receive my cookie. But after calling the url on the next day I am not logged in despite having my auth cookie (it's valid for 30 days). On my local machine hosted on IIS it works fine. Here are parts of my code:
Startup.cs:
ConfigureServices
services.ConfigureApplicationCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromDays(30);
options.SlidingExpiration = true;
options.LoginPath = new PathString("/Account/Login");
options.LogoutPath = new PathString("/Account/Logoff");
options.Cookie.Name = "MyApplication";
options.Cookie.IsEssential = true;
});
I am using the ProtectPersonalData attribute to encrypt userdata in the database with a keyring:
services.AddIdentity<ApplicationUser, IdentityRole>(config =>
{
config.SignIn.RequireConfirmedEmail = true;
config.Stores.ProtectPersonalData = true;
config.Stores.MaxLengthForKeys = 128;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
Configure
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
And this is the cookie in Firefox:
[cookie][1]
In my understanding this cookie should be send to the server on every request for that domain. And even though Firefox states, that it was accessed last on the exact time of my request it has no effect.
If you need any further code let me know. Any help is appreciated!
[1]: https://i.stack.imgur.com/UTSuR.png
Seems like everything was ok with my code. The error was within the IIS Configuration. As I am using DataProtection the ApplicationPool should have "load userprofile" set to true, because otherwise it can not store the keyring and data is lost after application shutdown/restart. After changing that on the production server it seems to be working now.

.Net Core 3.1 - Google Auth Cookie Not Persisting

I recently upgraded my ASP.Net Core MVC web app to .Net Core 3.1, and ever since, the Google External login cookie hasn't persisted properly as it did before the upgrade. The code itself didn't change at all, the app was just upgraded from .Net Core 2.0 to .Net Core 3.1.
The login flow works (user clicks login button, Google login screen appears, user logs in with Google Credentials/selects existing Google user and is sent back to the web app), but at random times (sometimes 30-60 seconds after login), the user's session randomly ends and the user is redirected back to the login screen. I've tested this extensively on localhost and the issue does not occur, but happens frequently on the hosting service I'm using (MochaHost).
Has anyone else had this issue with .Net Core 3.1?
The ConfigureServices method used at startup is below for reference.
public void ConfigureServices(IServiceCollection services)
{
services.AddLogging();
services.AddResponseCompression(options =>
{
options.Providers.Add<GzipCompressionProvider>();
options.EnableForHttps = true;
});
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new RequireHttpsAttribute());
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(Configuration["ConnectionStrings:MySQL"]));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddUserStore<UserStore>()
.AddDefaultTokenProviders();
services.AddAuthentication().AddGoogle(options =>
{
options.ClientId = Configuration["Authentication:Google:ClientId"];
options.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
options.CallbackPath = new PathString("/signin-google");
});
services.ConfigureApplicationCookie(options =>
{
options.AccessDeniedPath = "/error/401";
options.Cookie.Name = "MyApp";
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(180);
options.LoginPath = "/login";
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
options.SlidingExpiration = true;
});
services.AddMvc(option => option.EnableEndpointRouting = false);
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IFileProvider>(new PhysicalFileProvider(Configuration.GetValue<string>("RootFilePath")));
var serviceAccountFilePath = GetGoogleServiceAccountCredentialPath();
var googleCredential = GoogleCredential.FromFile(serviceAccountFilePath);
services.AddSingleton(StorageClient.Create(googleCredential));
}
In my case, the issue was that Data Protection key storage was not available via user profile or HKLM registry after the .Net Core upgrade. I'm not sure if this is related to having to switch to 64-bit app pool mode after the upgrade to .Net Core 3.1 or not, but the bottom line is data protection keys were only being stored in memory. After shifting from server to server via the load balancer, the user keys were lost, causing a redirect back to the login page.
Sample Log entries:
2020-11-20 09:00:21.162 -08:00 [INF] Starting web host
2020-11-20 09:00:21.572 -08:00 [WRN] Using an in-memory repository. Keys will not be persisted to storage.
2020-11-20 09:00:21.574 -08:00 [WRN] Neither user profile nor HKLM registry available. Using an ephemeral key repository. Protected data will be unavailable when application exits.
I had to add the below code to use a folder on the hosting service to store key files so the user's session would persist:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(Configuration.GetValue<string>("KeyStorePath")));

Asp.Net Core MVC with Windows Authentication on IIS

I have an ASP.NET Core MVC application with Windows Authentication. I published it on IIS server in local network of our company. All works fine, all users log in with their rights. But each time when they open a browser they need to enter their credentials. Each time we see a window for entering the user name and password. How to make a logon automatic?
I added this strings to Startup.cs
public void ConfigureServices(IServiceCollection services)
{
…
services.AddAuthentication(IISDefaults.AuthenticationScheme);
//custom authorization
services.AddAuthorization(options =>
{
options.AddPolicy("Operator", policy => policy.AddRequirements(new CheckADGroupRequirement(Configuration["RolesConfig:Operator"], Configuration["RolesConfig:Manager"])));
options.AddPolicy("Manager", policy => policy.AddRequirements(new CheckADGroupRequirement(Configuration["RolesConfig:Manager"])));
});
services.AddSingleton<IAuthorizationHandler, CheckADGroupHandler>();
//custom authorization
…
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
…
app.UseAuthentication();
…
}
In IIS I set to Enabled only Windows Authentication
The only solution I found it was set Automatic logon in Internet Options but I think it’s bad practice.

Azure AD SSO: .Net Core 2.1 Single Sign On Based On Organization's Office 365 Username&Password

I have created an ASP.NET Core 2.1 MVC web application and I have used a simple login form to authenticate the users. Now We have decided to remove the login form and use a single sign-on option with my Organization's Office 365 user credentials or my office’s outlook username & password and followed the following Microsoft website but I could not choose the right SSO one.
This web app is a MVP (minimum viable product) project so we just don't want to use our own authentication & authorization process and only my organization people going to use this app so we have decided to use the Organization's Azure AD SSO. I am not using SAML or WS-Federation protocols in my web app but I just wanted to implement the SSO for my project.
I searched many sites on the internet, a few websites explained "No code is required to configure SSO but only Azure AD configurations" and some other websites explained with some piece of code also. So now I am totally confused that how should I achieve the SSO for my simple web application.
Hosted environment: Azure App Service
Application users: only organization users (internal web app)
My Startup.cs code:
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.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.AddSession(options =>
{
options.Cookie.IsEssential = true;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
//Fetching Connection string from APPSETTINGS.JSON
var ConnectionString = Configuration.GetConnectionString("MbkDbConstr");
//Entity Framework
services.AddDbContext<ShardingDbContext>(options => options.UseSqlServer(ConnectionString));
//Automapper Configuration
AutoMapperConfiguration.Configure();
}
// 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.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSession();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller:required}/{action}/{id?}",
defaults: new { controller = "UserAccount", action = "UserLogin" });
});
}
}
Note: I have configured the app.UseAuthentication() & other functions but authentication part not used inside my projects.
If you want to Authenticate your users with App Services, refer the document to see how to enable AAD Authentication in app services.
Generally for any web application, you can configure App Registration in Azure AD. You can configure claim attribute as well in order to use SSO feature. Refer the document for how to configure app registration in Azure AD.

Web Socket are not available on signalr core?

I am working on signalr core under asp.net core 2.2.I have mobile as well as
web signalr core clients,I have maintained cross domain connection.My web client
successgully connnected to signalr core, but my android client gives exception below,
"Web sockets are not available on your server",
hence , web client is also using web sockets transport layer, and it is in conencting state.
my server side code is in start up class
// 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.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.SetIsOriginAllowed((host) => true)/*WithOrigins("https://localhost:44381")*/
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// 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("/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.UseCors("CorsPolicy");
app.UseSignalR(routes =>
{
routes.MapHub<ChatHub>("/chatHub");
});
app.UseMvc();
}
Please , answer me, how i connect android signalr Client to signalr core serever?
You need to enable WebSockets support on your Server.
To enable WebSockets on Windows Server 2012 or later :
Use the Add Roles and Features wizard from the Manage menu or the link in Server Manager.
Select Role-based or Feature-based Installation. Select Next.
Select the appropriate server (the local server is selected by default). Select Next.
Expand Web Server (IIS) in the Roles tree, expand Web Server, and then expand Application Development.
Select WebSocket Protocol. Select Next.
If additional features aren't needed, select Next.
Select Install.
When the installation completes, select Close to exit the wizard.

Categories