sly_Chandan
sly_Chandan

Reputation: 3515

Custom authentication module inheriting IHttpModule issue

LoginPage.aspx:-

protected void Button1_Click(object sender, EventArgs e)
            {
                Context.Items["Username"] = txtUserId.Text;
                Context.Items["Password"] = txtPassword.Text;
                //
                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, Context.Items["Username"].ToString(), DateTime.Now, DateTime.Now.AddMinutes(10), true, "users", FormsAuthentication.FormsCookiePath);

                // Encrypt the cookie using the machine key for secure transport
                string hash = FormsAuthentication.Encrypt(ticket);
                HttpCookie cookie = new HttpCookie(
                   FormsAuthentication.FormsCookieName, // Name of auth cookie
                   hash); // Hashed ticket

                // Set the cookie's expiration time to the tickets expiration time
                if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;
                Response.Cookies.Add(cookie);
                Response.Redirect("Default.aspx");
            }

Global.asax file:-

void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            if (HttpContext.Current.User != null)
            {
                if (HttpContext.Current.User.Identity.IsAuthenticated)
                {
                    if (HttpContext.Current.User.Identity is FormsIdentity)
                    {
                        FormsIdentity id =
                            (FormsIdentity)HttpContext.Current.User.Identity;
                        FormsAuthenticationTicket ticket = id.Ticket;
                        // Get the stored user-data, in this case, our roles
                        string userData = ticket.UserData;
                        string[] roles = userData.Split(',');
                        HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(id, roles);
                        Response.Write(HttpContext.Current.User.Identity.Name);
                        Response.Redirect("Default.aspx");
                    }
                }
            }
        }

I get the following error after signing in

This webpage has a redirect loop.

The webpage at http://localhost:1067/Default.aspx has resulted in too many redirects. Clearing your cookies for this site or allowing third-party cookies may fix the problem. If not, it is possibly a server configuration issue and not a problem with your computer.

Upvotes: 0

Views: 6008

Answers (2)

Chris Haas
Chris Haas

Reputation: 55427

This is the rough idea of what your module should look like. Your module will run on every request. You don't invoke it or pass anything to it, it just automatically fires whenever a request is made that ASP.Net is set to process.

Your module will do two things, 1) authenticate a user in the login page, 2) authenticate a user on subsequent pages. The first step is to subscribe to the BeginRequest method which will be given the current HttpApplication as the first parameter. From there you need to determine if the user is on your login page or not. If they're not on your login page, check your session or cookie or querystring token, or whatever you're using to make sure that they're still valid. If they're invalid, bounce them back to the login page.

If they're on your login page and have made a POST, look at the raw form fields and validate them. TextBoxes, checkboxes, etc don't exist here, only raw form fields. If they're valid, set your authentication token however you want (session, cookies, etc). If they're invalid, either redirect to the login page or inject a "try again" message or something.

Also, if you double-post a message please reference it so that we can follow the chain of what was already said.

class MyModule : IHttpModule
{

    void IHttpModule.Init(HttpApplication context)
    {
        //Subscribe to the BeginRequest event
        context.BeginRequest += new EventHandler(this.Application_BeginRequest);
    }
    private void Application_BeginRequest(Object source, EventArgs e)
    {
        //Initialize our variables, null checks should be put here, too
        HttpApplication app = (HttpApplication)source;
        HttpContext context = app.Context;
        System.Web.SessionState.HttpSessionState s = context.Session;

        //Normally our module needs to validate every request to make sure our request is still authenticated.
        //The exception to that rule is on our logon page where they obviously don't have credentials yet.
        if(!context.Request.FilePath.ToLowerInvariant().StartsWith("/login.aspx")){
            //If we're here then we're not on the logon page, validate our current session according to whatever logic we want
            if (s != null && s["isvalid"] == "true"){
                return;
            }else{
                context.Response.Redirect("/login.aspx");
            }
        }else{
            //If we're here then we're on the login page itself. If there's a post, assume that they've hit the login button
            if (context.Request.HttpMethod == "POST")
            {
                //Whatever your form variables are called
                string username = context.Request.Form["username"];
                string password = context.Request.Form["password"];
                //Your own validation logic would go here
                if (MyCustomLogin.IsUserValid(username, password))
                {
                    s["isvalid"] = "true";
                    context.Response.Redirect("/Home.aspx");    
                }else{
                    s["isvalid"] = "false";
                    context.Response.Redirect("/login.aspx?error=invalid_login");
                }
            }else{
                //If we're here then the request is probably a GET or HEAD which would be from a person
                //initially browsing to our page so just do nothing and pass it through normally
            }
        }
    }
}

Upvotes: 2

Gboyega Sulaiman
Gboyega Sulaiman

Reputation: 641

There is no direct way to have access to this information in the module (for authenticated user, you can access the username via the context, but not the password). The module checks if a request is carrying required authentication information and serve or deny the request based on that. Unless you deliberately from the login page collect this information and store somewhere where you can access it in the module, e.g session. But ideally, storing password is not widely recommended, collect it use it for authentication and destroy.

You might ideally throw more light on the reason why you want to have access to this information in the module and guys can then suggest methods to accomplish it.

Edited, after Chandan comment:

@Chandan, your comment here suggest to me what you want to do is use httpmodule for your authentication as against using standard form authentication. If I am on track, then you can check this project on codeproject at http://www.codeproject.com/KB/web-security/AspNetCustomAuth.aspx. Goodluck

Upvotes: 0

Related Questions