为通用开发平台的下载模块增加支持多线程下载,并增加防范盗链和内部系统盗链(越权)问题...

平台中用到的所有附件都是统一管理的,当然下载模块也是统一管理的

原先写的下载程序不支持多线程下载,并且无法支持续传,经网上搜索相关资料,得到一个比较好的函数,如下:

 

 '输出文件到浏览器
    '_fileName:输出的文件名
    '_fullPath:实际文件(含路径)
    'SaveFile:标志 True    '
    '_speed:下载速度   xxx 字节/秒
    Public Shared Function ResponseFile(ByVal _fullPath As String, ByVal _fileName As String, ByVal SaveFile As Boolean, ByVal _speed As Long) As Boolean

        If Trim(_fullPath) = "" Then Return False
        If Trim(_fileName) = "" Then _fileName = Path.GetFileName(_fullPath)
        _fileName = _fileName.Replace(" ", "") '删除空格
        _fileName = _fileName.Replace("[", "") '
        _fileName = _fileName.Replace("]", "") '
        _fileName = _fileName.Replace("""", "") '
        _fileName = _fileName.Replace("'", "") '
        _fileName = _fileName.Replace("$", "") '
        _fileName = _fileName.Replace("%", "") '
        If _speed <= 0 Then _speed = 10000000000
        Try
            Dim input As New FileStream(_fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
            Dim reader As New BinaryReader(input)
            Try
                Current.Response.ClearContent()
                Current.Response.ClearHeaders()
                Current.Response.AddHeader("Accept-Ranges", "bytes")
                Current.Response.Buffer = False
                Dim length As Long = input.Length
                Dim offset As Long = 0
                Dim num3 As Double = 10240
                Dim millisecondsTimeout As Integer = (CInt(Math.Floor(CDbl(((1000 * num3) / CDbl(_speed))))) + 1)
                If (Not Current.Request.Headers.Item("Range") Is Nothing) Then
                    Current.Response.StatusCode = 206
                    offset = Convert.ToInt64(Current.Request.Headers.Item("Range").Split(New Char() {"="c, "-"c})(1))
                End If
                Current.Response.AddHeader("Content-Length", (length - offset).ToString)
                Current.Response.AddHeader("Connection", "Keep-Alive")
                Current.Response.ContentType = GetFileContentType(Path.GetExtension(_fileName))
                Current.Response.AddHeader("Content-Disposition", (IIf(SaveFile, "attachment;", "") & "filename=" & HttpUtility.UrlEncode(_fileName, Encoding.UTF8)))
                Current.Response.ContentEncoding = Encoding.Default
                reader.BaseStream.Seek(offset, SeekOrigin.Begin)
                Dim num5 As Integer = (CInt(Math.Floor(CDbl((CDbl((length - offset)) / num3)))) + 1)
                Dim i As Integer
                For i = 0 To num5 - 1
                    If Current.Response.IsClientConnected Then ' 检查客户端是否在线
                        Current.Response.BinaryWrite(reader.ReadBytes(Integer.Parse(num3.ToString))) ' 读取数据到缓冲区
                        System.Threading.Thread.Sleep(millisecondsTimeout)
                    Else
                        i = num5
                    End If
                Next i
            Catch
                Return False
            Finally
                reader.Close()
                input.Close()
            End Try
            Current.Response.End()
        Catch
            Return False
        End Try
        Return True
    End Function

需要Imports System.Web.HttpContext

上述函数就能够支持多线程下载了,并且支持限速。

接下来就是考虑如何防范系统外部的用户盗链和系统内部其他用户的盗链(越权)访问

这方面我一直不知道有什么比较好的解决方案,下载模块调用入口原本是INC/ShowAttachFile.Aspx?File_ID=xxxx

其中的File_ID是真实的索引ID,通过这个索引ID就能够下载数据

防止外部盗链的方法很容易,只要判断帐号有没有登录就解决了,难就难在如何防止当前用户把这个地址发给其他用户,其他用户得到这个地址后能否获得文件,如果能够获得文件,那就是越权访问了(他本没有权限访问该文件的)

有不少的方法,有的人说,在后台增加一个授权字段,把授权情况写到该字段里面,在页面里进行验证,这种方法当然具有可行性,问题是过于复杂,整个系统到处都有可能用到了附件,我们的系统授权都是针对菜单进行授权的,并不是针对附件的,如果要有,无疑增加了授权的复杂性。

所以我在想一种更简单的解决方案

我个人认为关键还是出在下载模块入口上INC/ShowAttachFile.Aspx?File_ID=xxxx

如果我们的xxxx不传送真实的索引ID,而是传送一个真实的索引ID和当前用户作密码一块加密后的数据(密文),然后在下载模块中将该密文还原成真实索引ID,不就解决了越权访问问题吗?

我的系统就是这样解决越权问题的

用到一队加解密算法

密文=加密(真实的文件ID,密码)

其中密码采用当前系统的登录帐号

下载模块就改成了INC/ShowAttachFile.Aspx?File_ID=密文这种调用

在下载模块第一步操作就调用了解密算法

真实的文件ID=解密(密文,密码)

加密,解密算法是一对可逆算法,两者只要密码相同,就能够还原数据,这种算法网上非常多。

因为这个算法用到了密码跟当前登录名有关,所以如果当前登录名不同,这个链接地址拷贝给了别人之后,他是无法解密得到正确的文件ID号的,也就无法越权访问文件了。

 

 

 

转载于:https://www.cnblogs.com/laoyang/archive/2009/06/14/1503282.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值