有没有一种方法可以限制对ASMX Web服务的访问,即限制asmx页面和其WSDL的访问?

16

我有一个基于C# .NET的Web服务,需要对其进行访问限制。我已经要求我的使用者在调用服务时使用用户名和密码。但是,是否有一种方法可以限制对实际的asmx页面和WSDL的访问?我需要通过用户名/密码和IP地址对Web服务进行访问限制。如果用户没有正确的凭据,我不希望他们知道Web服务中存在哪些Web方法。

这可以通过IIS完成吗?我知道我可以通过IIS限制IP地址,但我能否也使用用户名/密码?

除了IIS以外,还有其他的方法吗?也许可以使用C#.NET来解决此问题?

6个回答

40

既然是ASMX,你可以在其中使用整个ASP.NET运行时堆栈。

步骤1 - 通过.config管理资源

为您想要保护的资源应用<location>标记。假设它是单个ASMX文件,您可以简单地在web.config中执行以下操作:

<location path="MyWebService.asmx">
    <system.web>
        <!-- resource specific options will go here -->
    </system.web>
</location>

第二步 - 认证您的用户

您需要决定如何实际上对用户进行身份验证。有几种方法可以做到这一点,也有几种身份验证标准可以利用。您需要选择适合您的方法。

如果您位于内部网络并使用Windows身份验证,则我强烈建议利用它,因为这是真正最简单的设置选项。然而,如果您的服务通过互联网被访问,则Windows身份验证不是一个选项,您需要从Web标准中进行选择。其中最简单的是基本身份验证,但您应该仅在SSL上使用此选项,因为用户名/密码未加密(只有Base64编码)。比这更高级的是摘要身份验证,它不需要SSL,因为用户名/密码使用MD5哈希发送。对于最终安全性,您可以选择SSL v3,其中向您API的每个用户发放特定客户端证书。

现在,您选择哪种安全选项就决定了还需要做什么。如果您选择Windows安全性,只需将以下元素添加到我们在第1步中开始的<system.web>元素即可:

<authentication mode="Windows" />

剩下的安全协议需要更多的工作。ASP.NET不提供基本认证、摘要认证或SSL v3的内在支持。从技术上讲,你可以利用IIS来为你完成这种类型的身份验证,但它始终会映射到Windows用户。如果这对你是一个选择,那么只需保留<authentication mode="Windows" />元素并相应地配置IIS即可。然而,如果这不是一个选项,可能是因为你根本无法控制IIS/ActiveDirectory,或者需要对自定义用户数据库进行身份验证,那么这意味着你需要连接一个自定义的HttpModule来提供对这些安全协议的支持。

第三步 - 保护资源

保护资源最简单的方法就是基本上说:“不允许任何没有成功进行某种方式认证的人进入此资源”。使用以下授权配置来实现:

<authorization>
    <deny users="?" />
</authorization>

如果你只想允许特定的用户,可以改为执行以下操作:

<authorization>
    <deny users="*" />
    <allow users="jdoe, msmith" />
</authorization>

另一种方法是定义角色(组),并将资源锁定为特殊角色,然后将您想要访问该资源的用户放入该角色中。

<authorization>
    <deny users="*" />
    <allow roles="My Service Users" />
</authorization>

这在Windows身份验证中很好地映射,因为您可以设置Windows组,并让MIS团队使用ActiveDirectory管理该组中的用户。但是,如果您使用的安全实现通过其IPrincipal实现公开角色,则该功能也可用于非Windows身份验证。


这真的是一个很好的答案。但是,我错过了一件事:我需要将授权规则存储在数据库中,因此无法使用通过web.config的声明性方法。目前,我在每个Web方法中都有一些用于这些检查的代码(例如'if(!this.isauthorized())return“未经授权!”')。有什么想法可以消除这些并在一个地方进行检查吗?可能有一个事件可以使用,也许通过HTTP处理程序等? - Matt
在使用摘要认证时,用户凭据将根据Windows活动目录进行检查。当我们为外部用户设计Web服务时,如何使用摘要认证验证用户凭据并对其进行数据库检查。 - Mou

0
<add path="*.asmx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True" /> 添加到 web.config 文件的 <httpHandlers> 部分。

似乎没有任何区别。asmx文件仍然可以被浏览。 - Anders Lindén

0

您可以通过从Machine.config中的元素中删除Documentation协议来停止显示WSDL。

更新: Web服务身份验证-最佳实践? 如果您的用户有用户名/密码,您可以通过HTTPS使用HTTP基本身份验证。

您还可以以稍微不同的方式实现它。对您的Web服务的第一个调用应该是身份验证方法。客户端进行身份验证并接收身份验证令牌。此令牌应呈现给您的Web服务公开的所有其他方法。


但是如果我这样做,没有人能够看到WSDL。 - Jon
True。但这取决于您是否需要让合法用户看到WSDL,可能是一件好事。 - DmitryK
如何从基于asmx的Web服务中删除文档? - flalar
1
在<system.web><webservices><protocols>中添加<remove name="Documentation"/>就可以解决问题了。请参阅以下链接以获取更多选项:http://msdn.microsoft.com/zh-cn/library/4yx7be39(VS.71).aspx - flalar

0

我不知道这对你来说有多实际,但你可以考虑升级到WCF。WCF与ASMX Web服务完全向后兼容,并且通过定义MEX(元数据交换)端点来控制是否公开WSDL。没有MEX端点,就没有WSDL。


我希望我能升级...但不幸的是,现在这并不是一个选项。 - Jon
停止 WCF 的公开并不意味着它不能被调用,我仍然可以通过 AJAX 调用来调用它。 - WtFudgE

0

有两个选项:在不同的端口上创建完全不同的站点,并锁定权限。这样做的优点是提供了一定程度的“安全性通过混淆”(半开玩笑...)或者您可以在现有站点下添加一个新的应用程序(相同的端口,不同的路径),使用不同的应用程序池并分配权限。

无论哪种情况,您的 Web 服务都无法与各种 ASP.NET “事物”进行通信,例如应用程序对象(它会,但不会是相同的)。部署只稍微麻烦一些:部署相同的二进制文件,但仅包括一个 Web 服务文件。


0

你可以使用 HttpModule 进行身份验证。SSL + BasicAuthentication 可以与其他工具链获得最佳互操作性。

在 HttpModule 中,您可以访问请求并拒绝未经身份验证的用户仅访问 .asmx 请求。即使在这种情况下,您也可以允许他们访问 WSDL。


1
你能给我更多关于这个的信息吗?也许可以给一个如何实现的例子吗?听起来很有前途。 - Jon
当然,但目前我离周一之前装有VS的机器远着呢。这很简单,但我脑子里没有全部的代码。g - Robert Giesecke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接