问题
I have an ASP.Net Core (3.1) web app that takes advantage of Identity. It works as desired on my dev box, but does not redirect to login in production.
Let me explain. I have a home/landing page with links to actions all over it. If a user clicks on an action that requires Authentication (I am using the [Authorize] tag to specify that in my controller), then the app should redirect to the Login page to allow the user to login first and then redirect to the desired action that they click. This works like magic almost completely out of the box with Identity on my dev machine. When I push to production, this doesn't work like that. It just sits on the home page with the URL changed to the action URL of the action clicked, which is OK I guess - at least it still enforces the Authentication - but I want the redirection.
My production machine is a redhat linux server with apache and .netcore 3.1 setup on it.
Here is my Startup:
public class Startup
{
//private readonly IConfiguration _configuration;
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.AddDistributedMemoryCache();
services.AddControllersWithViews();
services.AddRazorPages();
services.AddDbContext<AAPDbContext>(options => {
options.UseSqlServer(Configuration.GetConnectionString("AAP"));
});
services.AddDbContext<AuthDbContext>(options => {
options.UseSqlServer(Configuration.GetConnectionString("AAP"));
});
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);
}
// 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");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
Here is my IdentityHostingStartup (added by Scaffolding and then tweaked):
public class IdentityHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) => {
services.AddDbContext<AuthDbContext>(options =>
options.UseSqlServer(
context.Configuration.GetConnectionString("AAP")));
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<ApplicationRole>()
.AddRoleManager<RoleManager<ApplicationRole>>()
.AddEntityFrameworkStores<AuthDbContext>();
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
});
}
}
I'm hoping this is a weird situation where some setting needs to be flipped on the linux box that is different b/c my dev box is a Win10 machine.
Here is my config file for Apache:
<VirtualHost *:*>
RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
</VirtualHost>
<VirtualHost *:80>
ServerName blah blah
RewriteEngine on
RewriteRule .* https://blahblahblah [R=302,QSA,L]
</VirtualHost>
<VirtualHost *:443>
ServerName blah blah
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
</VirtualHost>
回答1:
Based on the behavior that you're describing it's likely that something on your server is handling the unauthorized request before it's getting to your web application
回答2:
I figured this out. It was the config file on the server.
I had it set to:
<VirtualHost *:*>
RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
</VirtualHost>
<VirtualHost *:80>
ServerName <removed server name>
RewriteEngine on
RewriteRule .* https://<removed server name> [R=302,QSA,L]
</VirtualHost>
<VirtualHost *:443>
ServerName <removed server name>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
</VirtualHost>
...and it should have been:
<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
</VirtualHost>
<VirtualHost *:443>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
ErrorLog /var/log/httpd/<removedappname>-error.log
CustomLog /var/log/httpd/<removedappname>-access.log common
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:!RC4+RSA:+HIGH:+MEDIUM:!LOW:!RC4
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
</VirtualHost>
..which I found here: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-3.1
Moral of the story: never trust a server guy when he's guessing just like you. Always follow the documentation.
来源:https://stackoverflow.com/questions/63271862/identity-with-asp-net-core-3-1-on-not-authenticated-the-app-is-not-redirectin