简体   繁体   中英

How to use basic http authorization together with forms authentication in .net applications

I would like to add basic HTTP authorization to entire site that uses forms authentication for some protected pages. The idea is to present development stage of the portal to the client so he could play with it, but to secure the entire site with additional simple login and password on HTTP level so no one else could access it. Classic tag in web.config is not enough here because the portal could use forms authentication (with user registration) as a part of its functionality. I would like to authorize user by HTTP prior to forms authentication which can happen later.

The HTTP level authorization should have logins and password configured by administrator (ie in a text file).

Would it be possible to achieve this functionality by custom http module?

UPDATE:

The idea is to create configuration-level way of securing application. Forms Authentication is not en option here because handling different account types and roles would require changes in the application.

I've already resolved this issue with simple custom module that tests HTTP Authorization header and response with HTTP 401. This module can be attached to any website via Web.Config

SOLUTION:

Module class:

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();
    }
}

In web.config:

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

this could be what you're looking for:

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

but anyway it would be more simple to cover all the pages with login and use just forms authentification.

You can also consider using roles, cut off anonymous users, then create one role for not yet registered users and another role for registered users. In the final stage you just disable the first role and enable anonymous users

You can even set different rules at folder level, this is another way to go

It certainly would be possible to do this with a custom module. You can (and I have, for other reasons) ignore ASP.NET's concepts of users and have your module return the 401 that insists upon a log-in or allow the request to continue, as appropriate. RFC 2617 has all you need to know on that. If you ignore ASP.NET's user objects then there won't be any interference between the standard authentication and the form authentication your application already uses.

Remember that basic is easily intercepted if not over HTTPS, in which case you may wish to use digest instead. Digest is a bit more complicated to do yourself, but certainly not terribly difficult, and is also documented in RFC 2617.

为什么不对整个站点使用表单身份验证,而对保护区和页面添加beta测试者角色?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM