Identity with ASP.Net Core 3.1 - on not authenticated, the app is not redirecting to Login in production like it does in dev

夙愿已清 提交于 2021-02-11 06:16:43

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!