自定义身份验证模块继承IHttpModule问题

时间:2011-02-03 05:41:35

标签: asp.net

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文件: -

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

登录后我收到以下错误

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.

2 个答案:

答案 0 :(得分:2)

这是您的模块应该是什么样子的粗略概念。您的模块将在每个请求上运行。您不会调用它或向其传递任何内容,只要发出ASP.Net设置为处理的请求,它就会自动触发。

您的模块将执行两项操作:1)在登录页面中对用户进行身份验证,2)在后续页面上对用户进行身份验证。第一步是订阅BeginRequest方法,该方法将以当前HttpApplication作为第一个参数。从那里,您需要确定用户是否在您的登录页面上。如果它们不在您的登录页面上,请检查您的会话或cookie或查询字符串令牌,或者您正在使用的任何内容,以确保它们仍然有效。如果它们无效,请将它们退回到登录页面。

如果他们在您的登录页面上并且已经发布了POST,请查看原始表单字段并验证它们。这里不存在TextBox,复选框等,只有原始表单字段。如果它们有效,请根据需要设置身份验证令牌(会话,cookie等)。如果它们无效,请重定向到登录页面或注入“再试一次”消息等。

此外,如果您双重发布消息,请reference it,以便我们可以按照已经说过的链接。

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
            }
        }
    }
}

答案 1 :(得分:0)

没有直接的方法可以访问模块中的此信息(对于经过身份验证的用户,您可以通过上下文访问用户名,但不能访问密码)。模块检查请求是否携带所需的身份验证信息,并根据该请求提供或拒绝请求。除非您故意从登录页面收集此信息并存储在您可以在模块中访问它的地方,例如会话。但理想情况下,不建议存储密码,收集它用于身份验证和销毁。

理想情况下,您可以更多地了解您希望在模块中访问此信息的原因,然后人们可以建议实现它的方法。

在Chandan评论之后编辑:

@Chandan,您在此处的评论告诉我您要做的是使用httpmodule进行身份验证,而不是使用标准表单身份验证。如果我正在进行中,那么您可以在http://www.codeproject.com/KB/web-security/AspNetCustomAuth.aspx的codeproject上查看此项目。古德勒克