我的网站中的身份验证和安全性 - 请咨询

时间:2010-05-27 10:13:41

标签: asp.net security forms-authentication session

我正在使用带有用户名/密码列表的数据库,以及一个允许用户输入用户名/密码的简单网络表单。

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

我的问题是:

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

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

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

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

  5. 建议和答案非常赞赏。

5 个答案:

答案 0 :(得分: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,//"martinfernandez@ispg.in",
                                            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 :(得分:1)

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

以下是初学者和Advance Web Developer必须遵循的一些常规安全措施。

       #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(跨站点请求伪造)攻击

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

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

将以下行添加到.htaccess文件中。

Options -Indexes

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

IP限制是一种先进而有效的方法,可以阻止未经授权的人员访问您网站的特定区域。 以下是IP限制对特定位置的访问的htaccess代码示例。

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:功能访问规则

添加&#34; _&#34;作为函数名称的前缀,我们可以防止从Web公开调用函数。当我们需要通过AJAX访问某些特定函数时,这是最佳实践。

7:锁定目录和文件权限

文件权限定义了谁可以对文件执行操作 &#34;读&#34; = 4:查看文件内容 &#34;写&#34; = 2:更改文件内容 &#34;执行&#34; = 1:运行程序文件或脚本。

8:阻止从Web浏览器

运行Cron作业

通过在页面中添加以下代码行,您可以保护您的网页免受网络浏览器的访问。

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

9:隐藏要由Google抓取的管理页面

您不希望搜索引擎将您的管理页面编入索引,因此您应该使用robots_txt文件阻止搜索引擎列出它们。

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

禁用“右键单击”作为查看网站源代码的方法,通过检查元素保护一般用户的网站内容。

11:使用CMS的强密码

保持练习以仅使用特殊字符设置随机密码。

12:让管理员目录难以猜测

黑客可能会使用扫描网络服务器上所有目录的脚本来获取“管理员”或“登录”等赠品名称,并且您的重要内容可能会被泄露。

13:更改数据库表前缀

添加前缀(项目名称和年份的混合),这对于安全方来说很难设定 为了说明,
A)BPM Supreme =&gt; bpm14_download
B)Glickin =&gt; gk15_admin
C)TravelWorthy =&gt; tw16_user

14:防止用户密码,与您的密码一样重要

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

15:隐藏错误日志

在开发模式下,保持错误报告&#34; ALL&#34;一旦我们去现场,将其改为&#34; 0&#34;不要忘记。在这里 参考:http://php.net/manual/en/function.error-reporting.php

答案 4 :(得分:0)

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

我在我的网站上使用它,你可以直接使用会员控制(登录表格,更改密码等),或者你可以自己动手。

我发现的唯一棘手的一点是在我的dB中设置成员资格表,视图和存储过程(你下载一个dB脚本),但实际上它实现起来相当简单。

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