ASP.NET MVC抓取动态生成的图片---涉及权限问题

活着生活 2013-08-13 04:49:11
在做一个ASP.NET MVC项目里,有多个模块,由多个部门合作开发,
现在遇到的问题涉及到3个模块:统计分析、公告管理、信息查看,其中统计分析、公告管理需要用户登录,未登录则跳转到登陆页,而信息查看不需要用户登录。
统计分析中,有些页面有一些统计图表,是用MvcChart动态生成的图片,实现是:
1. 页面上的图片类似这样:
<img src="/Analysis/SingleAnalysis/GetResultByYear?ID=3&year=2012&guid=DEBF000F-4C18-64E7-9B05-796B3300D2C7"/>

2. Action GetResultByYear 根据传入的参数,得到相关的一组数值后,生成图片

[NeedSignIn]
public ActionResult GetResultByYear(int ID= 0, int year = 0)
{
string XTitle = "时间(单位:月份)";
string YTitle = ControllerHelp.GetYTitle(int.Parse(nodeType));
var values = busiSvc.GetResultByYear(ID, year);
return File(MvcChart.DrawSeries(values, "", XTitle, YTitle, SeriesChartType.Column, true), "image/*");
}

“动态生成图片”(GetResultByYear)是需要验证用户登录状态的,未登录的话,会跳转到登录页面。
在另外一个公告管理模块里,需要抓取这些图片,然后插入到公告内容中,开始我是直接取的图片的src添加到公告内容中,也就是
<img src="/Analysis/SingleAnalysis/GetResultByYear?ID=3&year=2012&guid=DEBF000F-4C18-64E7-9B05-796B3300D2C7"/>

但是这样有个问题:在信息查看模块中,是不需要登录的,而不登录的情况下,查看包含上面这类图片的时候,图片加载会失败。
统计分析 这个模块是另外一个部门已经开发完成的,那么,在不修改统计分析模块代码的情况下,怎么解决这个问题呢?
开始我想到了一个方法:在公告管理模块对应的Action里,建一个WebClient,然后把图片保存到服务器,再根据文件路径生成图片的url,但实际运行的时候,发现下载的只是登陆页面……

System.Net.WebClient client = new System.Net.WebClient();
client.DownloadFile(imgUrl, filePath);

如何使WebClient继承当前用户的登录状态呢?

或者,用其它方式来解决这个问题?
...全文
293 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
活着生活 2013-08-26
  • 打赏
  • 举报
回复
引用 11 楼 jshi123 的回复:
派生webclient带上一个cookie container就能实现记住登录状态: 不过这样总觉得怪怪的,感觉hack自己的系统。。。
这样还是不行。 可能是我们的权限验证框架的问题。 唉…… 结贴吧。 多谢几位帮忙! 来者有份,按劳分配……
活着生活 2013-08-16
  • 打赏
  • 举报
回复
不小心点错发了…… 是感觉很怪…… 不过,貌似可行?回去试试,下班先……
活着生活 2013-08-16
  • 打赏
  • 举报
回复
引用 11 楼 jshi123 的回复:
派生webclient带上一个cookie container就能实现记住登录状态:

public class MyWebClient : WebClient
{
    private readonly CookieContainer m_container = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        HttpWebRequest webRequest = request as HttpWebRequest;
        if (webRequest != null)
        {
            webRequest.CookieContainer = m_container;
        }
        return request;
    }
}
然后调用的时候: var client = new MyWebClient(); wc.UploadValues("登录地址", new NameValueCollection {{"用户名", "xxxx"}, {"密码", "xxxx"}}); client.DownloadFile(imgUrl, filePath); 不过这样总觉得怪怪的,感觉hack自己的系统。。。
唉,痛苦中……
饕餮123 2013-08-16
  • 打赏
  • 举报
回复
引用 11 楼 jshi123 的回复:
派生webclient带上一个cookie container就能实现记住登录状态:

public class MyWebClient : WebClient
{
    private readonly CookieContainer m_container = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        HttpWebRequest webRequest = request as HttpWebRequest;
        if (webRequest != null)
        {
            webRequest.CookieContainer = m_container;
        }
        return request;
    }
}
然后调用的时候: var client = new MyWebClient(); wc.UploadValues("登录地址", new NameValueCollection {{"用户名", "xxxx"}, {"密码", "xxxx"}}); client.DownloadFile(imgUrl, filePath); 不过这样总觉得怪怪的,感觉hack自己的系统。。。
本来就是哇
jshi123 2013-08-16
  • 打赏
  • 举报
回复
派生webclient带上一个cookie container就能实现记住登录状态:

public class MyWebClient : WebClient
{
    private readonly CookieContainer m_container = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        HttpWebRequest webRequest = request as HttpWebRequest;
        if (webRequest != null)
        {
            webRequest.CookieContainer = m_container;
        }
        return request;
    }
}
然后调用的时候: var client = new MyWebClient(); wc.UploadValues("登录地址", new NameValueCollection {{"用户名", "xxxx"}, {"密码", "xxxx"}}); client.DownloadFile(imgUrl, filePath); 不过这样总觉得怪怪的,感觉hack自己的系统。。。
活着生活 2013-08-16
  • 打赏
  • 举报
回复
引用 9 楼 wjqqonline 的回复:
而你生成图片的方法的地方需要验证登录,而前台查看是不需要登录的,这样显然是冲突的,如果继续此思路,只能是后台登录查看此页面,把生成的图片保存到一个指定的文件夹,然后前台查看时直接用已经存在的图片文件(但是这样就不是实时的图片结果了,需要后台人员手动去生成图片)
不需要实时结果的。
引用 9 楼 wjqqonline 的回复:
二,换个思路,在验证的地方改动, 生成图片的这个方法页面加载时你肯定是判断的登录状态,那么在登录状态直接加一个判断来源url,


string url= Request.UrlReferrer.ToString();
if(url=="你前台要浏览的那个url")
     return true;
这样就能保证只有前台指定的那个页面和后台登录之后可以正常看到结果
悲剧的是:登录状态的判断也不是我能改的……
_沫尘 2013-08-16
  • 打赏
  • 举报
回复
一,继续按照楼主你的思路往下走, 你前台查看目前实际上是直接调用的生成图片的方法的那个页面实时生成(这和验证码是一个道理) 而你生成图片的方法的地方需要验证登录,而前台查看是不需要登录的,这样显然是冲突的,如果继续此思路,只能是后台登录查看此页面,把生成的图片保存到一个指定的文件夹,然后前台查看时直接用已经存在的图片文件(但是这样就不是实时的图片结果了,需要后台人员手动去生成图片) 二,换个思路,在验证的地方改动, 生成图片的这个方法页面加载时你肯定是判断的登录状态,那么在登录状态直接加一个判断来源url,


string url= Request.UrlReferrer.ToString();
if(url=="你前台要浏览的那个url")
     return true;
这样就能保证只有前台指定的那个页面和后台登录之后可以正常看到结果
活着生活 2013-08-16
  • 打赏
  • 举报
回复
引用 5 楼 a407121393 的回复:
[quote=引用 4 楼 jshi123 的回复:] 你可以另外做一个action,直接调用生成图片的方法: return new YourController().GetResultByYear(...) 然后把img.src指向你的action
那他的这个action必须要具有登录用的票据才可以去"调用生成图片的方法"[/quote] “在另外一个公告管理模块里,需要抓取这些图片,然后插入到公告内容中” 这个过程也是需要登录的,如果用这种方式的话,你说的这个Action其实是有登录状态的。 公告编辑完了发布之后,在信息查看模块中查看公告不需要登录。
活着生活 2013-08-16
  • 打赏
  • 举报
回复
引用 3 楼 tiwenid0 的回复:
在编辑中调用WebService将图片保存到服务器就行了
@tiwenid0 ??? 与WebService无关,只不过是同一个项目里的不同类库。 注:这三个项目的Controller都是独立的项目。
引用 6 楼 jshi123 的回复:
[quote=引用 5 楼 a407121393 的回复:] 那他的这个action必须要具有登录用的票据才可以去"调用生成图片的方法"
你看它的GetResultByYear方法,授权验证是用属性标签实现的,所以直接调用方法能够绕过验证。 不过这样new出来的controller没有ControlContext,所以和用IController.ProcessRequest()调用过来的还是有区别,到底管不管用,要看这个生成方法怎么写的。因为这种办法比较简单,我觉得楼主可以尝试一下。[/quote] @jshi123 “统计分析中,有些页面有一些统计图表,是用MvcChart动态生成的图片” 实际情况是这样的:后面的处理中并不是只需要调用GetResultByYear,而是有很多的图表,也就是说,有很多的类似GetResultByYear的Action。 你说的这个方法有可行性,最开始我也想过这种方式,不过,如果其它类似的Action也需要实现的,所以要实现的话,可能需要N多判断,或者IOC…… 我的想法是:有没有什么办法,能让WebClient继承当前用户的登录状态,或者用js什么的将图片保存到本地再上传到服务器(--!,2了点……)
jshi123 2013-08-14
  • 打赏
  • 举报
回复
引用 5 楼 a407121393 的回复:
那他的这个action必须要具有登录用的票据才可以去"调用生成图片的方法"
你看它的GetResultByYear方法,授权验证是用属性标签实现的,所以直接调用方法能够绕过验证。 不过这样new出来的controller没有ControlContext,所以和用IController.ProcessRequest()调用过来的还是有区别,到底管不管用,要看这个生成方法怎么写的。因为这种办法比较简单,我觉得楼主可以尝试一下。
饕餮123 2013-08-14
  • 打赏
  • 举报
回复
引用 4 楼 jshi123 的回复:
你可以另外做一个action,直接调用生成图片的方法: return new YourController().GetResultByYear(...) 然后把img.src指向你的action
那他的这个action必须要具有登录用的票据才可以去"调用生成图片的方法"
jshi123 2013-08-14
  • 打赏
  • 举报
回复
你可以另外做一个action,直接调用生成图片的方法: return new YourController().GetResultByYear(...) 然后把img.src指向你的action
tiwenid0 2013-08-14
  • 打赏
  • 举报
回复
在编辑中调用WebService将图片保存到服务器就行了
活着生活 2013-08-14
  • 打赏
  • 举报
回复
引用 1 楼 a407121393 的回复:
既然设置必须登录才能看到图片了,不登陆当然就不应该看到。。。。设置的有问题 WebClient需要把cookie或者urlid等保存用户状态的东东传过去才能有用户状态,这个要看你的用户登录机制是怎么实现的。
不是你理解的那样。 相当于 后台生成动态图片需要登录,后台编辑公告内容需要登录,前台查看公告内容不需要登陆。 现在的问题是,在不改后台动态生成图片的代码的情况下,在“编辑公告”中,怎么把这个动态图片转存到服务器。
饕餮123 2013-08-13
  • 打赏
  • 举报
回复
既然设置必须登录才能看到图片了,不登陆当然就不应该看到。。。。设置的有问题 WebClient需要把cookie或者urlid等保存用户状态的东东传过去才能有用户状态,这个要看你的用户登录机制是怎么实现的。

62,041

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧