表单身份验证了解context.user.identity

Dex*_*ter 18 c# asp.net forms-authentication

由于此过程的文档非常模糊且令人困惑(或过时),我想验证我是否正确执行并且没有遗漏任何步骤.

我正在尝试创建一个安全的登录系统,在浏览器关闭时到期.

- 在我的web.config中我有以下内容 -

<authentication mode="Forms">
      <forms loginUrl="~/Login.aspx" defaultUrl="Index.aspx" name=".ASPXFORMSAUTH" timeout="100" />
    </authentication>
    <authorization>
      <allow users="?" />
    </authorization>
    <machineKey decryption="AES" validation="SHA1" validationKey.......... />
Run Code Online (Sandbox Code Playgroud)

所以我有一个带有用户名/密码文本框的登录表单和这个按钮:

<asp:Button ID="LoginButton" runat="Server" OnClick="Login_Authenticate" Text="Sign in" />
Run Code Online (Sandbox Code Playgroud)

在Login_Authenticate内部我执行以下操作:

protected void Login_Authenticate(object sender, EventArgs e){
string userName = UserName.Text;
string password = Password.Text;

bool Authenticated = false;

// Here's code that makes sure that Username and Password is CORRECT
if(AuthClass.Authenticate(userName, password)){
 Authenticated = true;
}
// error checking does happen here.

if (Authenticated)
{
  FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(30), rememberUserName, String.Empty, FormsAuthentication.FormsCookiePath);
  string encryptedCookie = FormsAuthentication.Encrypt(ticket);
  HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookie);
  cookie.Expires = DateTime.Now.AddMinutes(30);
  Response.Cookies.Add(cookie);
  //FormsAuthentication.RedirectFromLoginPage(userName, false);

  Response.Redirect("MainPage.aspx");
}
}
Run Code Online (Sandbox Code Playgroud)

---在MasterPage.master.cs中我在Page_Init()中有以下检查---

if (Context.User.Identity.IsAuthenticated)
    {
      int userid = (int)Session["userid"];
      if (userid == null)
      {
        userid = GetUserID(Context.User.Identity.Name);
        if (userid != null)
        {
          Session["userid"] = userid;
        }
      }
    }
Run Code Online (Sandbox Code Playgroud)

编辑:--- GLOBAL.ASAX; 一些我不太确定的代码是正确的或知道它的作用

protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        // look if any security information exists for this request
        if (HttpContext.Current.User != null)
        {
            // see if this user is authenticated, any authenticated cookie (ticket) exists for this user
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                // see if the authentication is done using FormsAuthentication
                if (HttpContext.Current.User.Identity is FormsIdentity)
                {
                    // Get the roles stored for this request from the ticket
                    // get the identity of the user
                    FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity;
                    //Get the form authentication ticket of the user
                    FormsAuthenticationTicket ticket = identity.Ticket;
                    //Get the roles stored as UserData into ticket
                    string[] roles = { };
                    //Create general prrincipal and assign it to current request

                    HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(identity, roles);
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

---从那时起,在每个页面上,我使用Session userid来收集用户信息和内容,并确保用户具有适当的身份验证和组角色权限.

这都是正确的吗?或者我必须在任何地方解密?

这足以使安全的用户登录吗?或者我应该不打扰表单身份验证并找到自己的方式来制作自己的cookie并自己管理它?

Joe*_*ger 12

代码编写方式登录将在浏览器会话中保持不变.它可能有助于理解正在发生的事情的基础知识.

对于基于cookie的身份验证方法,实际上有三个操作:

1)登录 - 验证用户的凭据并在其浏览器上创建和存储cookie.

2)注销 - 只需从浏览器中删除cookie(通过使cookie过期或删除它)

3)Per Request Validation(您的Application_AuthenticateRequest部分) - 检查是否存在cookie,如果存在,请获取用户的Identity和Roles并设置HttpContext.Current.User.

通常,FormsAuthentication模块会将大部分内容隐藏起来.看起来你的代码试图使用FormAuthentication的一些元素(比如FormsAuthenticationTicket和FormsIdentity.只要你得到你想要的东西,这很好.

您的Login_Authenticate方法看起来很好除了您在cookie上设置过期.即使您关闭并重新打开浏览器,这也会使cookie保持不变.由于这不是您想要的行为,我不会设置cookie过期.设置此项就像检查"记住我"复选框一样.

每次从应用程序提供页面时,都会运行Application_AuthenticateRequest中的代码.它的主要工作是设置HttpContext.Current.User.通常,如果没有用户登录,则User为null或匿名用户.如果用户已登录,则应代表您的用户.

如果您正在执行这三项操作,那么您可以在代码中的任何位置引用HttpContext.Current.User来决定要显示的信息级别.例如,如果要将页面限制为仅限管理员,则可以调用HttpContext.Current.Users.IsInRole("Administrators"),如果调用返回false,则将它们重定向离开页面.

希望这可以帮助.


Fré*_*ric 6

关于这个问题,我有点迟了,但对于那些试图实现表单身份验证同时保持简单的人(就像我试图的那样),这里有我在msdn上找到的相关最新文档:http: //msdn.microsoft.com /en-us/library/xdt4thhy(v=vs.100).aspx

简而言之,不要搞砸设置cookie,检查它们,实例化门票或校长,......把它留给FormsAuthentication上课.

登录时,如果您的代码具有检查凭据并且它们是有效的,则只需致电

FormsAuthentication.RedirectFromLoginPage(yourUserId, false);
Run Code Online (Sandbox Code Playgroud)

它会为您设置身份验证cookie,与重定向相结合就足够了." false"用于不持久授权:它将在浏览器关闭(或授权超时)时丢失.

在已经过身份验证的请求中,没有任何内容可以通过代码检查以确保您的身份验证有效.使用Context.User.Identity.Name知道谁是连接(将字符串yourUserId以上).

在显式注销时,请致电

FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
Run Code Online (Sandbox Code Playgroud)

并在web.config中配置表单身份验证.

<system.web>
  <authentication mode="Forms">
    <forms loginUrl="yourLoginPage" defaultUrl="yourDefaultPageAfterLogin">
    </forms>
  </authentication>
  <authorization>
    <deny users="?" />
  </authorization>
</system.web>
Run Code Online (Sandbox Code Playgroud)

请注意,对于MVC应用程序,应从配置中删除授权部分,并使用AuthorizeAttribute已注册的全局过滤器属性进行处理,并使用AllowAnonymousAttributeon控制器或需要它的操作.(MVC 4;在此之前,需要创建自己的属性来处理它.)