问题:
系统原来只有一台服务器,随着成长,增加了新的服务器。在新服上,架设网站后,网站内的图像文件夹是采用虚拟目录技术假设的,实际的目录指向旧服务器共享的目录。并且全站对jpg文件进行了映射,交由ASP.NET 解析处理。
现在发现新服上无法访问图像文件夹,报告无法加载dll组件。
处理与分析:
无法加载的dll组件,是因为系统试图在图像文件虚拟目录下找这些组件或者web.config;
如果虚拟目录指向本地目录就可以,指向其他机器就不行。
如果取消对jpg的拦截处理,则虚拟目录下的图像文件可以访问(两台服务器上共享时,已经采用了统一的新建的IIS_WPG级别新用户
My_APP,IIS虚拟目录也采用此帐户为匿名用户)说明,这些虚拟目录缺乏可执行权限。
但是因为这些目录是两台机器上两个网站共用的,因此不想设置在目录下设置 web.config。
解决方案:
创建一个新的目录Share,在此目录中解析 jpg; 但是真正的 jpg 文件并不放在这里,而是放在站外的 DFS (分布式文件系统)中。
现在的问题,如果让网站当中新建的 Share 目录下的 ashx 文件访问到 DFS 当中的图片?
方法1:采用帐号模拟
1 // 帐号模拟:采用 Windows API 直接模拟
2 <%@ WebHandler Language="C#" Class="ShowPP" %>
3 using System;
4 using System.Runtime.InteropServices;
5 using System.Web;
6 using System.Security.Principal;
7
8 public class ShowPP : IHttpHandler {
9
10 [DllImport("Advapi32.DLL")]
11 static extern bool LogonUser(
12 string sUserName,
13 string sDomain,
14 string sUserPassword,
15 uint dwLogonType,
16 uint dwLogonProvider,
17 out System.IntPtr token);
18 [DllImport("Kernel32.DLL")]
19 static extern void CloseHandle(System.IntPtr token);
20
21 public void ProcessRequest (HttpContext context) {
22
23 System.IntPtr pToken;
24 if (LogonUser("My_APP",string.Empty,"myapp_key",2,0,out pToken))
25 {
26 WindowsIdentity.Impersonate(pToken);
27 WindowsIdentity id = WindowsIdentity.GetCurrent();
28
29 context.Response.ContentType = "image/jpeg";
30 context.Response.BufferOutput = false;
31 context.Response.WriteFile(@"\\Server2\QQ\201105\20110527\Thumbnail\0a44c1f2-0cd7-3c563f366a6c.JPG");
32
33 CloseHandle(pToken);
34 }
35 }
36
37 public bool IsReusable {
38 get {
39 return false;
40 }
41 }
42 }
3 using System;
4 using System.Runtime.InteropServices;
5 using System.Web;
6 using System.Security.Principal;
7
8 public class ShowPP : IHttpHandler {
9
10 [DllImport("Advapi32.DLL")]
11 static extern bool LogonUser(
12 string sUserName,
13 string sDomain,
14 string sUserPassword,
15 uint dwLogonType,
16 uint dwLogonProvider,
17 out System.IntPtr token);
18 [DllImport("Kernel32.DLL")]
19 static extern void CloseHandle(System.IntPtr token);
20
21 public void ProcessRequest (HttpContext context) {
22
23 System.IntPtr pToken;
24 if (LogonUser("My_APP",string.Empty,"myapp_key",2,0,out pToken))
25 {
26 WindowsIdentity.Impersonate(pToken);
27 WindowsIdentity id = WindowsIdentity.GetCurrent();
28
29 context.Response.ContentType = "image/jpeg";
30 context.Response.BufferOutput = false;
31 context.Response.WriteFile(@"\\Server2\QQ\201105\20110527\Thumbnail\0a44c1f2-0cd7-3c563f366a6c.JPG");
32
33 CloseHandle(pToken);
34 }
35 }
36
37 public bool IsReusable {
38 get {
39 return false;
40 }
41 }
42 }
方法2:采用配置文件
<system.web>
<identity impersonate="true" userName="My_APP" password="myapp_key" />
</system.web>
此时就不用直接调用 Windows API了。
using System.Web;
using System;
public class ShowPP : IHttpHandler {
public void ProcessRequest (HttpContext context)
{
context.Response.ContentType = "image/jpeg";
context.Response.BufferOutput = false;
context.Response.WriteFile(@"\\Server2\QQ\201105\20110527\Thumbnail\0a44c1f2-0cd7-3c563f366a6c.JPG");
}
public bool IsReusable {
get {
return false;
}
}
}
using System;
public class ShowPP : IHttpHandler {
public void ProcessRequest (HttpContext context)
{
context.Response.ContentType = "image/jpeg";
context.Response.BufferOutput = false;
context.Response.WriteFile(@"\\Server2\QQ\201105\20110527\Thumbnail\0a44c1f2-0cd7-3c563f366a6c.JPG");
}
public bool IsReusable {
get {
return false;
}
}
}