Asp.net 继承IHttpModule问题的自定义身份验证模块

Asp.net 继承IHttpModule问题的自定义身份验证模块,asp.net,Asp.net,LoginPage.aspx:- protected void Button1_Click(object sender, EventArgs e) { Context.Items["Username"] = txtUserId.Text; Context.Items["Password"] = txtPassword.Text; // Forms

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.

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

理想情况下,您可以在模块中提供更多关于您希望访问这些信息的原因的信息,然后大家可以建议实现这些信息的方法

编辑,在Chandan评论之后:


@Chandan,您在这里的评论向我建议,您要做的是使用httpmodule进行身份验证,而不是使用标准形式的身份验证。如果我在轨道上,那么你可以在codeproject上查看这个项目。Goodluck

这是您的模块的大致外观。您的模块将在每次请求时运行。您不调用它,也不向它传递任何信息,它只是在ASP.Net设置为处理的请求发出时自动激发

您的模块将做两件事,1)在登录页面验证用户,2)在后续页面验证用户。第一步是订阅
BeginRequest
方法,该方法将被赋予当前
HttpApplication
作为第一个参数。从那里你需要确定用户是否在你的登录页面上。如果它们不在您的登录页面上,请检查您的会话、cookie或querystring令牌,或者您正在使用的任何东西,以确保它们仍然有效。如果它们无效,请将它们反弹回登录页面

如果他们在您的登录页面上并发表了帖子,请查看原始表单字段并验证它们。这里不存在文本框、复选框等,只有原始表单字段。如果它们有效,则根据需要设置身份验证令牌(会话、cookie等)。如果它们无效,请重定向到登录页面或插入“重试”消息或其他内容

另外,如果你双重发布一条信息,请这样我们就可以按照已经说过的话来做

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

有些文章提到了自定义身份验证,但他们不从文本框中获取数据,而是从url中传递的变量中获取数据作为参数。考虑到这种情况,我想authenticaterequest真的做不了什么。您能给我推荐一些请求级事件的好例子吗?这些事件在模块级处理时很有用。为什么会出现重定向错误?
Application\u AuthenticateRequest
会在每个请求上触发,因此当您登录时,会按预期发送到Default.aspx。但是,在呈现该页面之前,将调用此代码,并将浏览器重定向到Default.aspx。但在呈现之前,此代码再次运行,并再次将浏览器重定向到Default.aspx。这个过程一直重复,直到有东西检测到(如果你幸运的话)无限重定向。另外,请不要更改你的整个帖子。您可以通过更改对其进行修改,但是您已经从IHttpModule切换到使用global.asax事件,并且这些事件是独立的。如果你选择了另一个方向,请创建一个新问题并参考旧问题(如果相关)。很棒的示例代码!但是,会话总是空的,所以我不得不使用PreRequestHandlerExecute事件而不是BeginRequest。。。