开发者

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 (i.e 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开发者_如何学C.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>


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.


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


Why not use the forms authentication for the entire site and add a beta-testers role for the protected area and pages?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜