使用wmi引起的 System.UnauthorizedAccessException:拒绝访问

昨天在万网尝试发布公司的网站,是请一家设计公司做的,asp.net。发布之后,其他功能都正常,但就是后台管理登陆之后进不去:

提示  System.UnauthorizedAccessException:拒绝访问

System.UnauthorizedAccessException:拒绝访问

使用wmi引起的 System.UnauthorizedAccessException:拒绝访问_第1张图片


但是有一点很奇怪,公司的另一个网站,也在万网托管,服务器环境一模一样,后台管理也是用的同一套程序,却可以正常进入后台而不报错。

于是花了将近一天的时间把两个网站的代码比较了个遍,愣是没有发现什么实质性的不同。

因为自己也不了解asp.net,查了半天都查不出来,网上百度的,都一些常见的原因,解决的办法无非是修改 web.config文件或者是修改 IIS设置,但这是万网的托管服务,IIS什么的都没有问题,网上那些方法都不起作用,看来是另有原因。

无奈之下找了万网客服,最终,对方的工程师找到了问题的原因,是因为这个网站的登陆功能中用到了wmi(这个wmi我也是第一次听说),而万网的服务器设置是不允许使用wmi的,因此会提示拒绝访问某个资源。

下面就来说说这个问题的详细情况以及解决的办法:

一开始,客服大概说了下是wmi的问题,说是我的网站程序尝试去获取网卡信息,所以被拒绝。那么我第一步就要去找到程序中使用到wmi的地方:

使用wmi引起的 System.UnauthorizedAccessException:拒绝访问_第2张图片

通过百度,我发现C#中用到wmi的地方都会引用System.management , 但是很可惜,找遍了所有 .aspx.cs 文件,也没找到这个引用,难道这个网站程序确实没有使用wmi?

很无奈得把找不到wmi操作的事情告诉了客服:

使用wmi引起的 System.UnauthorizedAccessException:拒绝访问_第3张图片

不过,客服这次给出了更详细的解答:

使用wmi引起的 System.UnauthorizedAccessException:拒绝访问_第4张图片

这次,我总算有点开窍了,在 aspx.cs文件中找不到System.management引用,并不代表没有wmi操作,这种操作完全可以放在 dll文件中进行!下面是客服给我的dll截图:

使用wmi引起的 System.UnauthorizedAccessException:拒绝访问_第5张图片

这里就很清楚了,这个 GetLocalMac() 方法试图获取服务器的网卡Mac地址。那网站程序为什么要获取服务器的网卡Mac地址呢?想来想去无非就是要记录登录日志吧,于是查看了网站的数据库,果然,日志中确实有Mac地址字段:

使用wmi引起的 System.UnauthorizedAccessException:拒绝访问_第6张图片

接下来,就该找出程序中哪里调用了wmi操作了。

第一,很自然地就能想到,在Login 这个操作中应该会进行日志记录,也就是包含了获取网卡的操作;

第二,根据保存的信息来看,也确实是登录操作时报错;

 if (Administrator.ManageUser.Login(UserName.Text, System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(UserPassword.Text, "MD5")))
因为上文那个dll文件的名字是Administrator.dll,所以看到这里的 Administrator.ManagUser.Login()...,也就很自然得想到可以通过反编译查看dll里面Login()方法的详细内容:

使用wmi引起的 System.UnauthorizedAccessException:拒绝访问_第7张图片

可以看到,Login方法的最后一步,确实进行了日志记录,那么,获取网卡的操作很有可能就在它的第一个参数中:Log.category.Login.ToString(),于是打开Administrator下面的Log,果然发现了GetLocalMac()方法!正是这个方法试图获取万网服务器的Mac地址被拒绝,因此报错。

使用wmi引起的 System.UnauthorizedAccessException:拒绝访问_第8张图片

好了,问题的原因总算是弄清楚了,可是,下面就遇到了实质性的问题,那怎样修改程序使它不记录网卡Mac地址呢?

这个wmi操作是在dll里面的,反正dll我是没法改,那怎么办呢?

忽然想起了另外一个能正常进入后台的网站,它的程序基本和这个网站是同一套,也是相同的dll,那么可以看看它是怎么修改的呢?

下面来比较一下:

1. 问题网站:

  if (Administrator.ManageUser.Login(UserName.Text, System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(UserPassword.Text, "MD5")))

2. 正常网站:

  if (Login(UserName.Text, System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(UserPassword.Text, "MD5")))

可以发现,区别在于这个正常的网站重写了一个Login()方法,用来替代原来的 Administrator.ManageUser.Login() 这个dll中的方法调用,那再来看看这个重写的Login()方法是怎么写的呢?

public static bool Login(string UserName, string UserPassword)
        {
           
            bool result = Administrator.ManageUser.ValidateManageUser(UserName, UserPassword);
            if (result)
            {
                Administrator.ManageUser user = new Administrator.ManageUser(UserName);
                user.LastVisitTime = DateTime.Now;
                user.LoginTimes += 1;
                user.Update();
                HttpCookie Cookie = new HttpCookie("ManagerUser");
                Cookie.Name = "ManagerUser";
                Cookie.Value = HttpContext.Current.Server.UrlEncode(UserName);
                Cookie.Expires = DateTime.Now.Add(new TimeSpan(3, 0, 0));
                HttpContext.Current.Response.Cookies.Add(Cookie);
            }
            return result;

        }
这个方法看着很眼熟啊!下面再来看看dll中的Login方法是怎么写的吧:

public static bool Login(string UserName, string UserPassword)
{
    bool flag = ValidateManageUser(UserName, UserPassword);
    if (flag)
    {
        ManageUser user = new ManageUser(UserName);
        user.LastVisitTime = DateTime.Now;
        user.LoginTimes++;
        user.Update();
        HttpCookie cookie = new HttpCookie("ManagerUser");
        cookie.Name = "ManagerUser";
        cookie.Value = HttpContext.Current.Server.UrlEncode(UserName);
        cookie.Expires = DateTime.Now.Add(new TimeSpan(3, 0, 0));
        HttpContext.Current.Response.Cookies.Add(cookie);
        Log.CreateEventLog(Log.category.Login.ToString(), "管理员登录", "", 0, user.ManagerId, user.AdminUserName);
    }
    return flag;
}

 

不难发现,在 aspx.cs 文件中重写的Login()方法,其实是搬照了dll中的Login方法,只不过把最后一句记录日志的功能去掉了,并且在前面的语句中增加了Administrator.dll的引用。

于是也照此方法重写Login(),测试,成功!

经此一役,算是第一次实质性地接触了dll 的内容。


你可能感兴趣的:(使用wmi引起的 System.UnauthorizedAccessException:拒绝访问)