2012-01-10 100 views
18

由于关于此过程的文档非常含糊且令人困惑(或旧),因此我想验证我是否正确地执行了操作并且没有错过任何步骤。Forms身份验证理解context.user.identity

我想创建一个安全的登录系统,在浏览器关闭时过期。

- 在我的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.......... /> 

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

<asp:Button ID="LoginButton" runat="Server" OnClick="Login_Authenticate" Text="Sign in" /> 

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

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

编辑: --- 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); 
       } 
      } 
     } 
    } 

---从那时起,每一页上,我使用会话用户ID来收集用户信息和内容,并确保用户具有适当的身份验证和组角色权限。

这一切是否正确?或者我必须在任何地方解密任何东西?

这足以让一个安全的用户登录?还是应该不打扰表单身份验证,并找到我自己的方式来制作自己的cookie并自行管理它?

+0

如果什么代码失败总是验证方返回布尔认证=假真; //这是确保用户名和密码是CORRECT Authenticated = true的代码;这是你在顶部..但如果代码失败它从来没有设置认证回false。 – MethodMan 2012-01-10 21:11:51

+0

@DJKRAZE代码确实将其设置为false,如果有错误。我只是没有包含检查用户名/密码的冗长代码。 Authenticated = true只有在一切成功时才会发生。 – Dexter 2012-01-10 21:13:58

+0

增加了一些更多的澄清代码,包括我使用的Global.asax代码。我不知道它是否工作,我很困惑。 – Dexter 2012-01-10 21:25:03

回答

12

您的代码写入方式登录将持续浏览器会话。这可能有助于了解正在发生的事情的基础知识。

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

1)登录 - 验证用户的凭据,并创建和存储在他们的浏览器的cookie。

2)注销 - 只需将删除浏览器中的cookie(由过期的饼干或删除它)

3)每请求验证(也就是部分是你的Application_AuthenticateRequest) - 检查,看是否有cookie存在,如果是,获取用户的标识和角色并设置HttpContext.Current.User。

通常情况下,FormsAuthentication模块将大部分隐藏起来。它看起来像你的代码正在尝试使用FormAuthentication的一些元素(如FormsAuthenticationTicket和FormsIdentity。只要你得到你想要的,这是很好的

你的Login_Authenticate方法看起来很好除了你设置过期即使你关闭并重新打开浏览器,这也会使cookie保持不变,因为这不是你想要的行为,所以我不会设置cookie过期时间,这个设置就像检查“记住我”复选框一样。

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

如果你正在做这三件事,那么你的代码中的任何地方都可以引用HttpContext.Current.User来决定你想要显示的信息级别。例如,如果您只想将页面限制为仅限管理员,则可以调用HttpContext.Current.Users.IsInRole(“Administrators”),如果调用返回false,则将它们从页面重定向。

希望这会有所帮助。

+0

我明白了。我与我自己是否要使用cookies并坚持 - 或者是否在浏览器关闭时结束会话。我仍然无法决定是否应该去安全或方便。 --- Application_AuthenticateRequest中的代码是否也适用于一切?我不需要解密或者我的代码中的任何地方的cookie?你是什​​么意思的FormsAuthentication隐藏,它究竟隐藏什么,为什么我不应该使用FormAuthentication门票?我不想在Current.Users中使用角色,因为无论如何我都会查询数据库以获取特定的角色系统。 – Dexter 2012-01-11 06:30:21

+0

由于您使用FormsCookieName设置cookie,并且启用了FormsAuthentication,因此在调用Application_AuthenticateRequest之前,Forms Authentication将解密cookie并为您设置HttpContext.Current.User。使用FormAuthentication门票是完全可以接受的。 – 2012-01-11 15:49:55

+0

对于最后一部分,使用角色 - 请记住,HttpContext.Current.User几乎在您的请求处理的任何地方都可用。为了避免为每个“角色”查询命中数据库,可以使用一次数据库调用为Application_AuthenticateRequest中的用户设置所有角色。考虑它是“每个请求角色缓存”。 – 2012-01-11 15:51:13

2

有没有在您的授权标签的问题,应该是:

<authorization> 
    <deny users="?" /> 
    <allow users="*" /> 
</authorization> 

,因为你要拒绝匿名用户。如果您解决了这个问题,您可以安全地从主页面和global.asax中删除所有内容 - 您不必将表单标识重新映射到存储在会话中的自定义标识。这是浪费资源,我不认为它会以重大的方式提高解决方案的安全性。你可以依靠表单cookie。

+0

啊我明白了。但我希望匿名用户可以看到,像主页面一样选择登录。我确实希望他们看到某些其他页面。我还需要使用MasterPage的东西,因为我需要每个页面上的用户ID,我必须在MasterPage上检查身份验证,否则ASP.net将如何知道哪些页面不允许匿名用户?我必须确保用户在很多页面上登录。 (if context.identity.IsAuthenticated是一个大的if/else树的一部分,所以还有其他的情况)。 – Dexter 2012-01-11 06:36:27

+0

另外我的重定向在最后不工作... – Dexter 2012-01-11 18:14:07

+0

这是什么意思“不工作”? – 2012-01-11 18:55:08

6

我有点晚了关于这个问题的,但对于那些试图实现窗体身份验证,同时保持事情简单(像我想),这里的有关最新文档我已经在MSDN上找到: http://msdn.microsoft.com/en-us/library/xdt4thhy(v=vs.100).aspx

简而言之,不要搞乱设置cookie,检查它们,实例化门票或校长,...留给FormsAuthentication班。

在日志上,当您的代码检查凭据,如果它们是有效的,只是叫

FormsAuthentication.RedirectFromLoginPage(yourUserId, false); 

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

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

在明确的退出,呼吁

FormsAuthentication.SignOut(); 
FormsAuthentication.RedirectToLoginPage(); 

而且具有在web.config中配置表单认证。

<system.web> 
    <authentication mode="Forms"> 
    <forms loginUrl="yourLoginPage" defaultUrl="yourDefaultPageAfterLogin"> 
    </forms> 
    </authentication> 
    <authorization> 
    <deny users="?" /> 
    </authorization> 
</system.web> 

注意,对于MVC应用程序的授权部分应该从配置中删除,并注册为全局筛选器属性AuthorizeAttribute处理,对控制器或动作需要它的AllowAnonymousAttribute使用。 (MVC 4;在此之前,需要创建自己的属性来处理该属性)。

相关问题