3

I'm making a test rig for an ActiveX HTTP control, and I need to create a web site to securely POST to. To keep things simple, I'm running the web app with the VS debug server; the web app project is part of the solution with the test application. NTLM authentication is not supported by the AX control. Is there any easy way to require very basic http authentication without NTLM or redirecting to a page form? I just need it to require a username and password during the post. Username and password content doesn't matter, so everything will be stored as plaintext.

I've tried the authentication mode in the Web.Config; Windows appears identical to NTLM (could be wrong there), Forms requires a form to connect and set a cookie through, Passport is beyond the scope of this project, and I don't know how I'd implement None. Any ideas?

I tried "authentication mode="Windows"" in the Web.Config, and checked the NTLM checkbox in the web app's "Web" tab.

6
  • unless; does a secure http POST require a secure GET first? Commented Jan 10, 2012 at 20:56
  • can you paste that to your original post just click edit and add it.. it's non readable in the state you have it in now... Commented Jan 10, 2012 at 20:57
  • sorry about that; fixed. Commented Jan 10, 2012 at 21:00
  • a few questions keys Request.Form.AllKeys when you debug are you seein the string array values..? this line here ListBox1.Items.Add(key + ": " + Request.Form[key]); is it returning a string or int are you perhaps wanting to assing Request.Form[key].ToString(); just looking at your code that I re-formatted for you.. it's not looking / making sense what you are trying to do.. what's the full method look like.. Have you thought about using Dictionary<string, string> you can work against KeyValuePair using a Dictionary<,> Commented Jan 10, 2012 at 21:05
  • This is just in the ASP.NET form load event, and it's all of the code outside of the automatically generated web app; the thing already works, and I don't need any assistance with the code I posted. What I'm asking about is enabling basic authentication within the debug server; the content of the page here doesn't matter. AllKeys is an ASP.NET collection, I didn't make it. They're string values. The reason I'm putting up that information is so I can confirm it when receiving it with the AX control. Commented Jan 10, 2012 at 21:18

2 Answers 2

6

You could implement your own basic HTTP authentication using ASP.NET. It doesn't seem like a very complicated spec, but see RFC1945 for all the details.

If I had to do it I'd start off with an HttpModule that runs on every request and checks the HTTP header HTTP_AUTHORIZATION. If it's the header for basic authentication, then you can decode username and password. If the header is missing or the username and password are incorrect, then you send back an HTTP 401 response and add the WWW-Authenticate header.

Something like this (not tested, but you get the idea):

public class BasicAuthenticationModule: IHttpModule
{
  public void Init(HttpApplication application)
  {
    application.AuthenticateRequest += new EventHandler(Do_Authentication);
  }

  private void Do_Authentication(object sender, EventArgs e)
  {
    var request = HttpContext.Current.Request;
    string header = request.Headers["HTTP_AUTHORIZATION"];
    if(header != null && header.StartsWith("Basic "))
    {
      // Header is good, let's check username and password
      string username = DecodeFromHeader(header, "username");
      string password = DecodeFromHeader(header, password);

      if(Validate(username, password) 
      {
        // Create a custom IPrincipal object to carry the user's identity
        HttpContext.Current.User = new BasicPrincipal(username);
      }
      else
      {
        Protect();
      }
    }
    else
    {
      Protect();
    }
  }

  private void Protect()
  {
    response.StatusCode = 401;
    response.Headers.Add("WWW-Authenticate", "Basic realm=\"Test\"");
    response.Write("You must authenticate");
    response.End();
  }

  private void DecodeFromHeader()
  {
    // Figure this out based on spec
    // It's basically base 64 decode and split on the :
    throw new NotImplementedException();
  }

  private bool Validate(string username, string password)
  {
    return (username == "foo" && pasword == "bar");
  }

  public void Dispose() {}

  public class BasicPrincipal : IPrincipal
  {
    // Implement simple class to hold the user's identity
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

thanks, this gave me some good ideas. I ended up basically just parsing the username and password out from the header on the main page from the post, and if it doesn't match the expected values, set the statuscode to 401. Thanks a lot for the code!
I know this thread is really old now but I was wondering if you would know why nothing seems to happen when I enter values into the Login dialog and click enter? The event doesn't get triggered and the user validation doesn't happen.
@Anto Did you register the example BasicAuthenticationModule in web.config? Its Init method will only be called if you add it the <httpModules> section in <system.web>' or the <modules>` element in <system.webServer> (depends on the integrated mode of the webserver).
2

michielvoo's answer is great, but for sheer simplicity, I went with this in the code for the page:

string authorization = Request.Headers["Authorization"];
string userInfo;
string username = "";
string password = "";
if (authorization != null)
{
     byte[] tempConverted = Convert.FromBase64String(authorization.Replace("Basic ", "").Trim());
     userInfo = System.Text.Encoding.UTF8.GetString(tempConverted);
     string[] usernamePassword = userInfo.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
     username = usernamePassword[0];
     password = usernamePassword[1];
}

if (username == "yourusername" && password == "yourpassword")
{
}
else
{
     Response.AddHeader("WWW-Authenticate", "Basic realm=\"Test\"");
     Response.StatusCode = 401;
     Response.End();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.