IIS 元数据库 GetObject 调用返回错误 424 需要对象错误
我们有一个在 Windows Server 2003 和 IIS6 上运行的 ASP Classic 网站,该网站会引发间歇性运行时错误 424 object required。我们已经追踪到初始化对元数据库的对象引用的行,如下所示(第二行):
MetaBasePath="IIS://" & ComputerName & "/" & StorageKey & "/" & DataAccessKey
Set ConfigKey=GetObject(MetaBasePath)
DataSource=ConfigKey.Get("ODBCDataSource")
UserName=ConfigKey.Get("ODBCUserName")
Password=ConfigKey.Get("ODBCPassword")
我已经在 stackoverflow(以及整个网络)中搜索了其他人遇到此问题的任何迹象,但绘制了一个空白的。有谁知道可能导致此问题的原因吗?是否有任何与性能相关的设置来控制访问元数据库的频率?我们可以采用哪些最佳实践措施来提高元数据库访问的效率?我们通过在元数据库中隐藏数据库访问详细信息来假设我们正在做正确的事情是否正确,或者这在安全性方面是否过度?
此问题影响了大约 1% 的页面点击率。
我们正在考虑一系列操作,包括检查服务器软件组件的补丁级别,并可能在上述代码周围添加一个循环,以继续尝试,直到元数据库对象正确初始化,但在我看来,这充其量只是一个短期修复。
非常欢迎建议! 谢谢, 克雷格.
附加信息:刚刚发现启用了 IIS5.0 隔离模式。我试图找出启用此功能的原因,但这是否相关?
We have an ASP Classic website running on Windows Server 2003 and IIS6 which is throwing intermittent runtime error 424 object required. We've tracked this down to the line which initialises the object reference to the metabase as shown below (second line):
MetaBasePath="IIS://" & ComputerName & "/" & StorageKey & "/" & DataAccessKey
Set ConfigKey=GetObject(MetaBasePath)
DataSource=ConfigKey.Get("ODBCDataSource")
UserName=ConfigKey.Get("ODBCUserName")
Password=ConfigKey.Get("ODBCPassword")
I've searched stackoverflow (and the web in general) for any signs of anyone else having this issue but have drawn a blank. Does anyone have any ideas what could be causing this? Are there any performance related settings which control the frequency of access to the Metabase? Are there any best practice measure we can employ to improve the efficiency of Metabase access? Are we correct in assuming that we are doing the right thing by hiding our database access details in the Metabase or is this overkill in terms of security?
This issue affects us on approximately 1% of page hits.
We are looking at a range of actions including checking the patch level of the server software components and potentially adding a loop around the above code to keep trying until the Metabase object is initialised correctly but this would at best be a short term fix in my opinion.
Advice most welcome!
Thanks,
Craig.
Additional info: Just discovered that IIS5.0 Isolation Mode is enabled. I'm trying to find out why this was enabled but could this be relevant?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
IIS 元数据库并不是为了安全,而只是为了方便。
它只是由多个虚拟服务器(IIS/ASP 应用程序)共享的数据的中央存储库。因此,如果您只是出于安全目的使用它,那么根本不需要元数据库。
因为:
您向谁“隐藏我们的数据库访问详细信息”?程序员?但他已经可以访问它了。将
ConfigKey.Get("ODBCPassword")
分配给密码后,任何response.write
都会显示它。即使这是在global.asa
中完成的,您也必须在某个地方将其转换为连接字符串(或将其存储在Application
变量中),因此.asp
页面可以创建数据库连接对象。在元数据库和对象创建之间的某个时刻,他将有权访问连接属性。甚至不要考虑通过在
global.asa
创建连接对象并将对象本身存储在 Application 变量中来防止这种情况发生。 (从而隐藏程序员可访问的文件的创建)。这不仅会杀死连接池,还会对性能造成巨大负面影响。如果您担心 ASP 页面的数据库安全性,我建议使用以下一些方法:
创建一个不同的数据库用户来访问网站,权限非常有限。含义仅限于 SELECT、INSERT、UPDATE、DELETE 和 EXECUTE(存储过程)。没有 DROP、CREATE、ALTER 等。这样,任何“密码泄露”或“程序员误用”都不会严重危害数据库。具有完全权限的“admin”用户密码永远无法在网站的任何位置访问(或使用)。
创建一个 ActiveX(或 COM、DCOM)DLL 来包装连接设置。它可以用 C#、VB.NET 甚至经典的 VB6 编写。它将从另一个(安全且无法通过 Web 访问)服务器文件读取登录名和密码,创建连接对象,并将其直接传递给 ASP。
因此,不要使用:
ASP 页面将使用:
配置文件本身甚至可以加密,因为解密算法将存储在编译后的代码中,而不是存储在纯文本 ASP 文件中。
也就是说,我并不是说元数据库毫无用处。它仍然是一个存储数据的好、方便的地方,因为:
可以在不更改任何代码行的情况下更改数据
多个网站可以共享数据,甚至当每个网站都有自己独立的应用程序时,
用户/NTFS 权限可以设置为只有授权人员才能更改数据,但网站用户(和 ASP 开发人员)可以只能读取
也就是说,“受限数据库用户”+“ COM 类连接包装器”是我工作过的大多数公司所使用的方法。当然,那些关心安全的人。其他人只是使用“在 global.asa 中硬编码的连接字符串,然后存储在应用程序变量中”。
IIS Metabases are NOT meant for security, but merely for convenience.
Its just a central repository for data shared by several virtual servers (IIS/ASP applications). So you if are using it just for security purposes, then Metabase is not needed at all.
Because:
Who are you "hiding our database access details" from? The programmer? But he HAS access to it already. After assigning
ConfigKey.Get("ODBCPassword")
to Password, anyresponse.write
would reveal it. Even if that is done inglobal.asa
, somewhere you will have to convert it to a connection string (or store it in anApplication
variable) so.asp
pages can create the database connection objects. At some point between the Metabase and the object creation he WILL have access to the connection properties.Dont even think about preventing this by creating the connection object at
global.asa
and storing the object itself in an Application variable. (thus hiding the creation from programmer-accesible files). Not only this kills connection pooling, but its a huge negative performance hit.If you are concerned about database security from ASP pages, here are some approaches i suggest:
Create a different database user for website access, with very limited priviledges. Meaning SELECT, INSERT, UPDATE, DELETE and EXECUTE (stored procedures) only. No DROP, CREATE, ALTER, etc. This way, any "password leakage" or "programmer misuse" would not seriously compromise the database. The "admin" user password, with full priviledges, would never be accessible (or used) anywhere in the website.
Create an ActiveX (or COM, DCOM) DLL to wrap the connection settings. It could be writen in C#, VB.NET or even classic VB6. It would read login and password from another (secure and web-innacessible) server file, create the connection object, and pass it to ASP directly.
So instead of using:
The ASP pages would use:
The config file itself could even be encrypted, as the decripit algorithm would be stored in the compiled code, NOT in a plain text ASP file.
That said, I dont mean the Metabase is useless. Its still a good, convenient place to store data, because:
Data can be changed without changing any line of code
Several websites can share data, even when each has it own isolated app
Centralized data is always easier to mantain than keeping config and include files scattered all over the filesystem
User/NTFS permititions can be set up in a way that only authorized people can change the data, but website users (and ASP developers) can only read it
That said, the "limited database user" + "COM class connection wrapper" is the approach used in most companies ive worked with. The ones concerned about security, of course. The others just use the "connection string hardcoded in global.asa then stored in application variable".