2010-05-27 46 views
2

我使用的数据库中包含用户名/密码列表以及允许用户输入用户名/密码的简单Web表单。我的网站的身份验证和安全 - 需要咨询

当他们提交页面时,我只需执行存储过程检查即可进行身份验证。如果他们被授权,则他们的用户详细信息(例如用户名,dob,地址,公司地址,其他重要信息)将存储在自定义用户对象中,然后存储在会话中。我创建的这个自定义User对象用于整个Web应用程序,也用于子站点(会话共享)。

我的问题/问题是:

  1. 是我的身份验证方法做事的正确方法是什么?

  2. 我发现用户抱怨说他们的会话已经过期,尽管他们“没有空闲”,可能是因为应用程序池回收?他们输入大量文本并发现他们的会话已过期,从而失去了输入的所有文本。我不确定会话确实是否偶尔重置,但是使用cookie/cookiless的表单身份验证是否可以解决问题?

  3. 或者,我应该在会话,cookie或其他内容中构建和存储用户对象,以便更“正确”并避免像点#2这样的情况。

  4. 如果我使用Forms Authentication路由,我认为我无法将自定义User对象存储在Forms Authentication cookie中,这是否意味着我将存储UserID,然后在每个页面上重新创建用户对象?这不会是服务器负载的巨大增长吗?

建议和答复非常感谢。

大号

回答

0
  1. 它并不真正关心你是否使用自己的身份验证系统,或使用这种简单场景时的默认会员供应商。
  2. 当应用程序可能每天有几次回收时,您应该避免使用会话状态InProc。而是将您的会话存储到数据库(SqlSessionState)或使用StateServer。然后,应用程序池可以整天回收,而不会干扰您的会话。将会话超时设置为60分钟或什么,将解决剩余的问题。 永远不要使用无Cookie会话(除非你知道你在做什么),,因为它们使得偷取会话的方式太容易
  3. 只需将其存储到会话中(或使用默认成员资格提供程序的配置文件)。不仅cookie容易读取,而且限制为4 KB。
  4. 不,您将拥有存储所有用户信息的配置文件。使用表单身份验证或将其数据存储到SqlSessionState的自定义系统无关紧要。成员资格提供者会将资料ID存储到一个cookie中,与会话状态相同将会话ID保存到一个cookie中。
+0

非常感谢您的支持:-) 我已经设置了我的网站以将会话存储在SQL DB中。 您是否大致了解使用了多少内存以及是否应该担心? 谢谢 – Ichirichi 2010-07-28 16:12:20

0

我的建议是使用asp.net成员资格和角色(微软)。这是一个非常好的安全解决方案 - 登录安全性,角色(权限)并存储在SQLServer数据库中(不确定它是否可以存储在别处)。

我在我的网站上使用它,您可以直接使用会员控制(登录表单,更改密码等),也可以自己推出。

我发现的唯一棘手的问题是在dB中设置成员表,视图和存储过程(你下载了一个dB脚本),但实际上这很简单。

Here's a link to asp.net membership and roles

+0

感谢您的建议。问题在于我们将用户名和密码存储在一个单独的(已经存在的数据库)中,所以我认为这不适合我。 – Ichirichi 2010-07-28 16:34:17

1

您可以使用ASP.NET Membership, Roles, Forms Authentication, and Security Resources 我会用举一个例子C#

仅供参考Forms Authentication in ASP.NET 2.0

//code for checking user name & password 
protected void btnlogin_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     if (txtUserName.Text.Trim() != "" && txtPassword.Text.Trim() != "") 
     { 
      User obj = objUser.UserAuthenticate(txtUserName.Text.Trim(), txtPassword.Text.Trim()); 
      if (obj != null) 
      { 
       //To set AuthenticationCookie of usertype "User" 
       SetAuthenticationCookie("User", obj.UserID.ToString(), obj.DisplayName); 

       HttpCookie usercookie = new HttpCookie("LoginTime"); 
       usercookie.Value = DateTime.Now.ToString(); 
       Response.Cookies.Add(usercookie); 
       HttpCookie namecookie = new HttpCookie("LoginName"); 
       namecookie.Value = obj.DisplayName; 
       Response.Cookies.Add(namecookie); 



      } 
      else 
      { 
       lblMsg.Text = "Invalid Username or Password."; 
      } 
     } 
     else 
     { 
      //lblMsg.Visible = true; 
     } 
    } 
    catch (Exception ex) 
    { 
     //lblMsg.Visible = true; 
     throw ex; 
    } 
} 

private void SetAuthenticationCookie(string role, string userid, string name) 
{ 

string userdata = "logintype=user|role=" + role + "|email=" + txtUserName.Text.Trim() + "|name=" + name; 

    FormsAuthenticationTicket faTicket = new FormsAuthenticationTicket(1, userid, 
     DateTime.Now, DateTime.Now.AddHours(+1), 
              false, userdata); 

    HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName,//"[email protected]", 
              FormsAuthentication.Encrypt(faTicket)); 

    authCookie.Expires = faTicket.Expiration; 
    Response.Cookies.Add(authCookie); 


} 

    //code inside global.asax.cs 
    protected void Application_AuthenticateRequest(object sender, EventArgs e) 
    { 
     if (Context.User != null && Context.User.Identity is FormsIdentity && Context.User.Identity.IsAuthenticated) 
     { 
      FormsAuthenticationTicket faTicket = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value); 

      string[] userdata = faTicket.UserData.Split("|".ToCharArray()); 
      string logintype = ""; 
      string email = ""; 
      string uname = ""; 
      string roleString = ""; 
      foreach (string s in userdata) 
      { 
       string keyname = s.Split("=".ToCharArray())[0]; 
       if (keyname == "logintype") 
       { 
        logintype = s.Split("=".ToCharArray())[1]; 
       } 
       else if (keyname == "role") 
       { 
        roleString = s.Split("=".ToCharArray())[1]; 
       } 
      } 
      string[] rolesArray = roleString.Split(";".ToCharArray()); 
      Context.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(faTicket), rolesArray); 
     } 
    } 
1

只要触及第4点 - 在内存中不存储每个人的“用户”对象并在每个HTTP请求中重新创建对象会更有效率。通过这种方式,您还可以重新验证登录详细信息 - 如果某人的帐户遭到入侵并且实际用户更改了密码以尝试保护其帐户,但“坏用户”已经登录,该怎么办?在您的安全机制下,由于用户数据被缓存,并且不会在每次回发中重新验证,所以“不良用户”可以继续浏览。

1

以下是一些初级和高级Web开发人员必须遵循的一般安全措施。


 #15 Steps To Secure Your Website 

1:防止图像盗链(IMP)

图片盗链是使用我们的网站,别人的图片网址,并使用他们的带宽的过程。为了防止这种谜团,我们可以通过在代码中添加以下行来阻止访问外部服务器。

RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain.com [NC] 
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L] 

2:防止CSRF(跨站请求伪造)攻击

为了防止您的GET CSRF攻击和POST请求的表单提交,您可以使用以下两种方法。
首先它为每个请求包含随机标记,这是为每个会话生成的唯一字符串。
第二种方法是为每个表单字段使用随机名称。

3:防止目录访问/禁用索引

添加下面一行到你的.htaccess文件。

Options -Indexes 

4:IP限制,保护您的私人和CMS登录

IP限制是先进而有效的方法来阻止未经授权的人员访问您的网站的特定区域有点方式。 这是一个示例htaccess代码,用于IP限制对特定位置的访问。

ALLOW USER BY IP 
<Limit GET POST> 
order deny,allow 
deny from all 
allow from 1.2.3.4 
</Limit> 

5:保护你的。htaccess文件

你可以在你的htaccess文件中写下这段代码,它不让任何人访问你的htaccess文件。

<Files ~ “^.*.([Hh][Tt][Aa])”> 
order allow,deny 
deny from all 
satisfy all 
</Files> 

6:功能访问规则

通过添加“_”作为函数名称的前缀,我们可以防止功能从网络上公开被调用。当我们只需要通过AJAX访问某些特定功能时,这是最佳实践。

7:锁定你的目录和文件权限

文件权限定义谁可以做什么到一个文件中。
“阅读”= 4:查看文件内容。
“写入”= 2:更改文件内容。
“执行”= 1:运行程序文件或脚本。

8:防止cron作业从Web浏览器

运行通过添加,下面的代码行中你的页面,可以保护您的网页从Web浏览器访问。

if(! $this->input->is_cli_request()) { 
      die("Only CLI Requests Allowed"); 
} 

9:隐藏的管理页面被谷歌

你不希望你的管理页面被搜索引擎收录,所以你应该使用ROBOTS_TXT文件从列出这些阻碍搜索引擎抓取。

10:禁用右键单击页面,如果不要求

禁用“右键”,以此来查看检查元素,以确保为广大用户提供网站内容的网站源代码。

11:用于CMS

不断实践使用强密码来设置随机密码,只有特殊字符。

12:请联系目录很难猜测

它可能发生,黑客可以利用该扫描所有的目录,Web服务器上像“管理员”或赠品的名称“登录”等脚本和显著的东西可能会泄露。

13:更改数据库表前缀

添加前缀这将是很难推测有担保方(项目名称和年份的混合物)。
为了说明,
A)BPM最高=> bpm14_download
B)Glickin => gk15_admin
C)TravelWorthy => tw16_user

14:防止用户的密码,这是因为重要的,因为你的

关于密码加密算法,使用sha1算法,而不是传统算法Md5,这是一种非常古老的方式,现在每个来源都变得不太安全。
参考:http://php.net/manual/en/function.sha1.php

15:隐藏错误日志

在发展方式转变,保持错误报告“ALL”,一旦我们去为“0”没有忘记LIVE变化。在这里
参考:http://php.net/manual/en/function.error-reporting.php