如何在.net应用程序中使用基本http授权和表单身份验证

时间:2011-03-18 09:30:22

标签: c# .net authentication forms-authentication http-basic-authentication

我想向整个网站添加基本HTTP授权,该网站对某些受保护的网页使用表单身份验证。我们的想法是将门户网站的开发阶段呈现给客户端,以便他可以使用它,但是为了保护整个站点,在HTTP级别上使用额外的简单登录和密码,这样其他任何人都无法访问它。 web.config中的经典标记在这里是不够的,因为门户网站可以使用表单身份验证(使用用户注册)作为其功能的一部分。 我希望在表单身份验证之前通过HTTP授权用户,这可能会在以后发生。

HTTP级别授权应具有管理员配置的登录名和密码(即在文本文件中)。

是否可以通过自定义http模块实现此功能?

更新

我们的想法是创建保护应用程序的配置级方法。此处不提供表单身份验证,因为处理不同的帐户类型和角色需要在应用程序中进行更改。

我已经使用简单的自定义模块解决了这个问题,该模块使用HTTP 401测试HTTP Authorization标头和响应。此模块可以通过Web附加到任何网站.Config

SOLUTION:

模块类:

public class BasicAuthModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(this.HttpApplicationBeginRequest);
    }

    private void HttpApplicationBeginRequest(object sender, EventArgs e)
    {
        var request = HttpContext.Current.Request;
        var response = HttpContext.Current.Response;
        string authHeader = request.Headers["Authorization"];
        if (string.IsNullOrEmpty(authHeader))
        {
            this.RequireAuthorization(response);
        }
        else
        {
            string authType = authHeader.Split(' ').First();
            string authData = authHeader.Split(' ').Last();
            if (authType.ToLower() == "basic")
            {
                byte[] bytes = Convert.FromBase64String(authData);
                string plainText = Encoding.UTF8.GetString(bytes);
                string login = plainText.Split(':').First();
                string password = plainText.Split(':').Last();
                if (!this.Validate(login, password))
                {
                    this.DenyAccess(response);
                }
            }
            else
            {
                this.DenyAccess(response);
            }
        }            
    }

    private bool Validate(string login, string password)
    {
        return (login == ConfigurationManager.AppSettings["AuthLogin"]) && (password == ConfigurationManager.AppSettings["AuthPwd"]);
    }

    private void RequireAuthorization(HttpResponse response)
    {
        response.AddHeader("WWW-Authenticate", "Basic realm=\"stage\"");
        response.StatusCode = 401;
        response.Status = "401 Authorization Required";
        response.ContentType = "text/html";
        response.End();
    }

    private void DenyAccess(HttpResponse response)
    {
        response.AddHeader("WWW-Authenticate", "Basic realm=\"stage\"")
        response.StatusCode = 401;
        response.Status = "401 Authorization Required";
        response.ContentType = "text/html";
        response.End();
    }
}

在web.config中:

<modules runAllManagedModulesForAllRequests="true">
  ...
  <add name="BasicAuthModule" type="MyNamespace.BasicAuthModule, MyNamespace.Module"/>
</modules>

3 个答案:

答案 0 :(得分:1)

这可能是你正在寻找的东西:

http://msdn.microsoft.com/en-us/library/aa479391.aspx#madam_topic4

但无论如何,用登录覆盖所有页面并使用表单验证会更简单。

您还可以考虑使用角色,切断匿名用户,然后为尚未注册的用户创建一个角色,为注册用户创建另一个角色。在最后阶段,您只需禁用第一个角色并启用匿名用户

您甚至可以在文件夹级别设置不同的规则,这是另一种方法

答案 1 :(得分:1)

使用自定义模块肯定可以做到这一点。您可以(并且由于其他原因)忽略ASP.NET的用户概念,并让您的模块返回坚持登录的401或允许请求继续,视情况而定。 RFC 2617有你需要知道的全部内容。如果忽略ASP.NET的用户对象,则标准身份验证与应用程序已使用的表单身份验证之间不会有任何干扰。

请记住,如果不是通过HTTPS,基本很容易被截获,在这种情况下,您可能希望使用摘要。摘要自己做起来有点复杂,但肯定不是非常困难,并且在RFC 2617中也有记录。

答案 2 :(得分:0)

为什么不对整个网站使用表单身份验证,并为受保护区域和页面添加beta-testers角色?