.net实现图片权限控制,对不同的帐户加水印

来源:岁月联盟 编辑:exp 时间:2012-01-09
本案列实现不同用户登录有不同的权限,如果是免费用户下载图片则在图片上加上水印,如果是收费用户则不加水印。另外实现登录次数过多自动锁定30分钟功能,防止暴力破解密码。
 
1.Users数据库表定义如下:
 /
 
 
数据字段说明如下:
 
“id”为主键,在本实例中将案列ID来判断用户名,所以ID会记录到请求的Session中;“username”为用户名,“password”为密码;“level”为用户等级,“ErrorTimes”为错误次数,记录客户登录的次数;“LastTimes”为最后登录的时间,当用户登录次数超过限制后,需等待多久时间才能登录。
 
2.在VS Studio中添加数据集,并设置以下2个方法:
 
(1)GetDataById(@id):获取数据库中的id
 
SELECT ErrorTimes, LastTimes, id, level, password, username FROM Users WHERE (id = @id)
 
 
 (2) GetDataByUserName(@username):获取数据库中的username
 
SELECT ErrorTimes, LastTimes, id, level, password, username FROM Users WHERE (username = @username)
 
(3)incErrorTimesById(@id):获取数据库的id,并设置ErrorTimes次数加1,上次登录时间为当前日期
 
UPDATE [Users] SET ErrorTimes=ErrorTimes+1,LastTimes=getdate() where id=@id
 
(4)ResetErrorTimesById(@id):设置当前登录ID的ErrorTimes为0次
 
UPDATE [Users] SET ErrorTimes=0 where <a href="mailto:id=@id">id=@id</a>
 

/
 
3.Default.aspx为首页,前端HTML代码如下:
 
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="图片权限控制._Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:Label ID="Label1" runat="server" Text="用户名:"></asp:Label>
    <asp:TextBox ID="UserName" runat="server" Width="176px"></asp:TextBox>
    <div>
   
        <asp:Label ID="Label2" runat="server" Text="密码:"></asp:Label>
        <asp:TextBox ID="PassWord" runat="server" Height="24px"
            style="margin-left: 15px" TextMode="Password" Width="179px"></asp:TextBox>
        <br />
        <asp:Label ID="ErrorMsg" runat="server" Visible="False"></asp:Label>
   
    </div>
    <asp:Button ID="LoginBtn" runat="server" Text="登录" onclick="LoginBtn_Click" />
    </form>
</body>
</html>
 
 
4.为登录按钮增加c#代码,Default.aspx.cs代码如下:
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using 图片权限控制.DataSetPicxsdTableAdapters;
 
namespace 图片权限控制
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
 
        }
 
        protected void LoginBtn_Click(object sender, EventArgs e)
        {
            UsersTableAdapter adapter = new UsersTableAdapter();
            var data =adapter.GetDataByUserName(UserName .Text );
            if (data.Count <= 0)
            {
                ErrorMsg.Text = "用户名不存在!";
                ErrorMsg.Visible = true;
            }
            else
            {
                var user = data.Single();//返回唯一的一条数据
                //如果上次时间和错误次数不为空,则执行以下代码
                if (!user.IsLastTimesNull() && !user.IsErrorTimesNull())
                {
 
                    double span = (DateTime.Now - user.LastTimes).TotalMinutes;//计算当前时间和上次错误时间的间隔
                    if (user.ErrorTimes > 3 && span <= 30)
                    {
                        ErrorMsg.Text = "密码错误过多,请30分钟后再试";
                        ErrorMsg.Visible = true;
                        return;
                    }
 
                }
                if (user.password == PassWord.Text)
                {
 
                    Session["是否登录"] = true;
                    Session["登录用户ID"] = user.id;//把当前用户ID存储到session中
                    //如果登录成功,则清除当前登录id的错误次数
                    adapter.ResetErrorTimesById(user.id );
                    Response.Redirect("DownloadList.aspx");
 
                }
                else
                {
                    adapter.incErrorTimesById(user.id );//当密码错误,当前登录ID的登录错误次数加1
                    ErrorMsg.Text = "密码错误";
                    ErrorMsg.Visible = true;
                }
 
 
            }
 
 
        }
    }
}
 
 
5.DownLoadList.aspx前端html代码如下:
 
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DownloadList.aspx.cs" Inherits="图片权限控制.DownloadList" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <a href="DownLoad.ashx?filename=1.jpg">图片1</a><br />
<a href="DownLoad.ashx?filename=2.jpg">图片2</a><br />
<a href="DownLoad.ashx?filename=3.jpg">图片3</a><br />
    </div>
    </form>
</body>
</html>
 
 
 
后台C#代码如下:主要显示登录的用户
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using 图片权限控制.DataSetPicxsdTableAdapters;
 
namespace 图片权限控制
{
    public partial class DownloadList : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //获取登录用户的id
           
            int UserId=(int)Context .Session ["登录用户Id"];
            //在数据表中查询当前ID的用户名
            UsersTableAdapter adapter = new UsersTableAdapter();
            var data = adapter.GetDataById(UserId );
            var user = data.Single();//返回唯一一条数据
            Response.Write("欢迎回来-"+user.username );
            Response.Write("<a href='Default.aspx'>登出</a>");
        }
    }
}
 
 
6.在DownLoadList.aspx页面点击图片下载,其数据会提交到一般处理应用程序DownLoad.ashx处理,在此处判断用户权限登录时间次数等。
 
从浏览器获取用户的session并判断是否登录。
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using 图片权限控制.DataSetPicxsdTableAdapters;
using System.Web.SessionState;
using System.Drawing;
using System.Drawing.Imaging;
 
 
namespace 图片权限控制
{
    /// <summary>
    /// $codebehindclassname$ 的摘要说明
    /// </summary>
   
    public class DownLoad : IHttpHandler,IRequiresSessionState  //注意:需要实现这个接口
    {
 
        public void ProcessRequest(HttpContext context)
        {
          
            string filename=context.Request ["filename"];
            context.Response.ContentType = "image/JPEG";
            string UrlFile = HttpUtility.UrlEncode(filename);
            context.Response.AddHeader("Content-Disposition",string.Format ("attachment:filename=/"{0}/"",UrlFile ));
            if (context.Session["是否登录"] == null)
            {
                context.Response.Redirect("redirectLogin.htm");
 
            }
            else
            {
                int userId=(int)context .Session ["登录用户Id"];//从session中获得登录用户的id
                UsersTableAdapter adapter = new UsersTableAdapter();
                var data = adapter.GetDataById(userId );
                var user = data.Single();
                if (user.level == 0)//普通用户
                {
                    //给免费用户添加水印
                    using (Bitmap bitmap = new Bitmap(context.Server.MapPath("images/" + filename)))
                    {
                        using (Graphics g = Graphics.FromImage(bitmap))
                        {
                            g.DrawString("免费用户使用--"+user .username,new Font("宋体",20),Brushes .Red ,0,0);
                        }
                        bitmap.Save(context .Response .OutputStream ,ImageFormat.Jpeg );
                    }
                }
                else//收费用户
                {
 
                    context.Response.WriteFile("images/"+filename);//有攻击漏洞
                }
 
            }
           
        }
 
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
 
 
7.如果判断用户没有登录,则会转向到redirectLogin.htm页面,此页面会倒计时3秒后跳转到Default.aspx登录页面
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title></title>
    <script type ="text/javascript" >
        var lefttiems = 3;
        setInterval(function() {
            if (lefttiems <0) {
                window.location.href = 'Default.aspx';
            }
            document.getElementById("left").innerText = lefttiems;
            lefttiems--;
 
        }, 1000);
   
   
    </script>
</head>
<body>
页面将在3秒后跳转到登录页面,如果页面没有跳转,请点击<a href ="Default.aspx">点击登录</a>还剩下
<div id="left">0</div>秒
</body>
</html>
 
 
 作者 ngy00988