此外,使用现有身份验证密码保护作为Azure WebApp托管的ASP.NET Core MVC网站 [英] Additionally password protect an ASP.NET Core MVC website hosted as Azure WebApp with existing authentication

查看:65
本文介绍了此外,使用现有身份验证密码保护作为Azure WebApp托管的ASP.NET Core MVC网站的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有ASP.NET Core Identity的现有ASP.NET Core MVC应用程序,在其中我结合使用signInManager.PasswordSignInAsync[Authorize]属性来强制用户登录到网站,并具有一定的作用等. .在本地和Azure WebApp中都可以正常工作.

I have an existing ASP.NET Core MVC application with ASP.NET Core Identity where I use a combination of signInManager.PasswordSignInAsync and [Authorize] attributes to enforce that a user is logged in to website, has a certain role et cetera. This works fine locally and in an Azure WebApp.

现在,我想将应用程序的预览版本发布到另一个Azure WebApp.这次,我希望每个访问者在显示该网站上的任何内容之前 输入另一组凭据.我想我想要一个类似.htaccess/BasicAuthenication的东西.但是,在用户输入第一组凭据之后,不应登录,因为他需要使用常规的登录程序(就像在实时版本中一样,该版本可以公开访问,但是其中某些页面要求用户登录).基本上,我只想在顶部添加另一层密码保护,而不会影响当前现有的身份验证.

Now, I want to publish a preview version of my application to another Azure WebApp. This time, I want each visitor to enter another set of credentials before anything from the website is being shown. I guess I'd like to have something like an .htaccess / BasicAuthenication equivalent. However, after a user entered the first set of credentials, he should not be logged in since he should need to use the normal login prodecure (just as in the live version which is publicly accessible but this has certain pages which require the user to be logged in). Basically, I just want to add another layer of password protection on top without impacting the currently existing authentication.

鉴于我希望允许使用预览密码的任何人访问,以下解决方案似乎不适用于我的情况:

Given that I want allow access to anyone with the preview password, the following solutions do not seem to work in my case:

  • 将对WebApp的访问权限限制为防火墙设置.客户端IP不会来自某个IP范围,它们将由其ISP动态分配.
  • 将单个用户帐户与Azure AD一起使用.这可能是我的后备(尽管我不确定如何确切实现),但我宁愿没有另一套个人用户凭据来注意.凭据甚至可以像预览//预览一样简单.
  • Limit the access to the WebApp as a firewall setting. The client IPs will not be from a certain IP range and they will be dynamically assigned by their ISP.
  • Use an individual user account with Azure AD in front. This might be my fallback (although I'm not sure on how to implement exactly) but I'd rather not have another set of individual user credentials to take care. The credentials could even be something as simple as preview // preview.

是否有一种简单的方法,例如在Startup类中添加两行代码来实现所需的第二级密码保护?

Is there a simple way like adding two lines of codes in the Startup class to achieve my desired second level of password protection?

推荐答案

您可以通过基本身份验证来进行第二次身份验证,这很简单,并且不需要太多代码.您将需要一个中间件,该中间件将在原始身份验证完成后进行拦截/调用

You can do a second auth via a basic auth, something simple and not too much code. You will need a middleware that will intercept/called after the original authentication is done

中间件

public class SecondaryBasicAuthenticationMiddleware : IMiddleware
{
    //CHANGE THIS TO SOMETHING STRONGER SO BRUTE FORCE ATTEMPTS CAN BE AVOIDED
    private const string UserName = "TestUser1";
    private const string Password = "TestPassword1";

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        //Only do the secondary auth if the user is already authenticated
        if (!context.User.Identity.IsAuthenticated)
        {
            string authHeader = context.Request.Headers["Authorization"];
            if (authHeader != null && authHeader.StartsWith("Basic "))
            {
                // Get the encoded username and password
                var encodedUsernamePassword = authHeader.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries)[1]?.Trim();

                // Decode from Base64 to string
                var decodedUsernamePassword = Encoding.UTF8.GetString(Convert.FromBase64String(encodedUsernamePassword));

                // Split username and password
                var username = decodedUsernamePassword.Split(':', 2)[0];
                var password = decodedUsernamePassword.Split(':', 2)[1];

                // Check if login is correct
                if (IsAuthorized(username, password))
                {                   
                    
                    await next.Invoke(context);
                    return;
                }
            }

            // Return authentication type (causes browser to show login dialog)
            context.Response.Headers["WWW-Authenticate"] = "Basic";

            // Return unauthorized
            context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        }
        else
        {
            await next.Invoke(context);
        }
    }

    //If you have a db another source you want to check then you can do that here
    private bool IsAuthorized(string username, string password) =>
        UserName == username && Password == password;
}

在启动时->配置(确保您在现有的身份验证和授权之后添加它)

    //Enable Swagger and SwaggerUI
    app.UseMiddleware<SecondaryBasicAuthenticationMiddleware>(); //can turn this into an extension if you wish

    app.UseAuthentication();
    app.UseAuthorization();        

在启动中-> ConfigureServices注册中间件

services.AddTransient<SecondaryBasicAuthenticationMiddleware>();

Chrome会弹出这样的基本身份验证对话框

这篇关于此外,使用现有身份验证密码保护作为Azure WebApp托管的ASP.NET Core MVC网站的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆