【参加讨论】Windows 身份验证和授权
使用对 .aspx 页所采用的方法,通过 Windows 身份验证来保证 XML Web 服务的安全性(详见基于 Windows 的身份验证一节)。若需要身份验证,请在 IIS 管理控制台中为您的应用程序启用“集成的 Windows 身份验证”,并禁用“匿名访问”。若要允许或拒绝特定的用户访问服务,请使用 ASP.NET 配置系统,或在服务文件本身中设置 ACL,如下例所示:
<configuration>
<system.web>
<authentication mode="Windows"/>
</system.web>
<location path="secureservice.asmx">
<system.web>
<authorization>
<allow users="Administrator"/>
<allow users="DOMAIN\Bradley"/>
<deny roles="BUILTIN\Power Users"/>
</authorization>
</system.web>
</location>
</configuration>
这非常适合已知 XML Web 服务的客户端将作为某个特定 Windows 用户运行的情况。更有趣的情况是客户端作为一个用户运行,但却代表另一个用户。请考虑一个 ASP.NET 页,它访问的安全 XML Web 服务不模拟访问它的客户端。对于这样的情况,在连接到 Web 服务前,应通过编程设置用户名和密码。下面的示例使用基本身份验证,并说明一个简单的 WebService:
<%@ WebService language="C#" Class="SecureService" %>
using System.Web.Services;
using System;
class SecureService : WebService {
[WebMethod]
public String SecureTest() {
return "Hello from the secure web service";
}
}
<%@ WebService language="VB" Class="SecureService" %>
Imports System.Web.Services
Imports System
Class SecureService : Inherits WebService
<WebMethod()> Public Function SecureTest As String
Return "Hello from the secure web service"
End
End Class
<%@ WebService language="JScript" Class="SecureService" %>
import System.Web.Services;
import System;
class SecureService extends WebService {
WebMethodAttribute function SecureTest() : String {
return "Hello from the secure web service";
}
}
|
| C# |
VB |
JScript |
|
可以在 IIS 中做适当的设置,要求对此服务进行基本身份验证,如下所示:
- 打开 IIS MMC 控制台。
- 在左边的窗格中,展开目录树查找虚拟目录。
- 在右边的窗格中,右击“Secureservice.asmx”并选择“属性”。
- 选择“文件安全性”选项卡。在“匿名访问和验证控件”下,单击“编辑”。
- 禁用匿名访问。
- 禁用集成 Windows 身份验证。
- 启用基本身份验证。
- 单击“确定”保存这些设置并退出 MMC 控制台。
基 WebService 代理类提供两个属性:Username 和 Password。可以使用这两个属性指定凭据,并通过凭据连接到远程 Web 服务。必须将它们设置成 Web 服务的计算机或域上的有效 Windows 凭据。
<%@ Import Namespace="SecureService" %>
<html>
<script language="C#" runat="server">
public void Page_Load(Object sender, EventArgs e) {
SecureService s = new SecureService();
s.Credentials = new System.Net.NetworkCredential("Administrator", "test123");
Message.Text = s.SecureTest();
}
</script>
<body>
<h4><font face="verdana">
<asp:Label id="Message" runat="server"/>
</font></h4>
</body>
</html>
<%@ Import Namespace="SecureService" %>
<html>
<script language="VB" runat="server">
Public Sub Page_Load(sender As Object, e As EventArgs)
Dim s As New SecureService
s.Credentials = New System.Net.NetworkCredential("Administrator", "test123")
Message.Text = s.SecureTest()
End Sub
</script>
<body>
<h4><font face="verdana">
<asp:Label id="Message" runat="server"/>
</font></h4>
</body>
</html>
<%@ Import Namespace="SecureService" %>
<html>
<script language="JScript" runat="server">
public function Page_Load(sender : Object, e : EventArgs) {
SecureService s = new SecureService();
s.Credentials = new System.Net.NetworkCredential("Administrator", "test123");
Message.Text = s.SecureTest();
}
</script>
<body>
<h4><font face="verdana">
<asp:Label id="Message" runat="server"/>
</font></h4>
</body>
</html>
|
| C# |
VB |
JScript |
|
基 WebService 类还提供 System.Security.Principal.IPrincipal 类型的 User 属性,该属性可用来检索有关客户端用户的信息。此外,可以使用 ASP.NET 配置系统中的 Authorization 节授权对 Web 服务的访问。
使用 Soap 标头自定义身份验证和授权
Windows 身份验证非常适合 Intranet 方案,这种情况下您是对自己的域中的用户进行身份验证。然而在 Internet 上,您可能需要对 SQL 数据库执行自定义身份验证和授权。在这种情况中,应向服务传递自定义凭据(如用户名和密码),并让服务自己处理身份验证和授权。
将额外的信息连同请求一起传递给 XML Web 服务的简便方法是通过 SOAP 标头。为此,需要在服务中定义一个从 SOAPHeader 派生的类,然后将服务的公共字段声明为该类型。这在服务的公共合同中公开,并且当从 WebServiceUtil.exe 创建代理时可由客户端使用,如下例所示:
using System.Web.Services;
using System.Web.Services.Protocols;
// AuthHeader class extends from SoapHeader
public class AuthHeader : SoapHeader {
public string Username;
public string Password;
}
public class HeaderService : WebService {
public AuthHeader sHeader;
...
}
Imports System.Web.Services
Imports System.Web.Services.Protocols
' AuthHeader class extends from SoapHeader
Public Class AuthHeader : Inherits SoapHeader
Public Username As String
Public Password As String
End Class
Public Class HeaderService : Inherits WebService
Public sHeader As AuthHeader
...
End Class
import System.Web.Services;
import System.Web.Services.Protocols;
// AuthHeader class extends from SoapHeader
public class AuthHeader extends SoapHeader {
public var Username:String;
public var Password:String;
}
public class HeaderService extends WebService {
public var sHeader:AuthHeader;
...
}
|
| C# |
VB |
JScript |
|
服务中的每个 WebMethod 都可以使用 SoapHeader 自定义属性定义一组关联的标头。默认情况下,标头是必需的,但也可以定义可选标头。SoapHeader 属性指定公共字段的名称或者 Client 或 Server 类的属性(本标题中称为 Headers 属性)。在为输入标头调用方法前,WebService 设置 Headers 属性的值;而当方法为输出标头返回时,WebService 检索该值。有关输出标头或可选标头的更多信息,请参阅 .NET 框架 SDK 文档。
[WebMethod(Description="This method requires a custom soap header set by the caller")]
[SoapHeader("sHeader")]
public string SecureMethod() {
if (sHeader == null)
return "ERROR: Please supply credentials";
else
return "USER: " + sHeader.Username;
}
<WebMethod(), SoapHeader("sHeader")> Public Function SecureMethod() As String
If (sHeader Is Nothing)
Return "ERROR: Please supply credentials"
Else
Return "USER: " & sHeader.Username
End If
End Function
WebMethodAttribute(Description="This method requires a custom soap header set by the caller")
SoapHeaderAttribute("sHeader")
public string SecureMethod() {
if (sHeader == null)
return "ERROR: Please supply credentials";
else
return "USER: " + sHeader.Username;
}
|
| C# |
VB |
JScript |
|
然后,客户端在调用要求标头的方法之前,直接在代理类上设置标头,如下面的示例所示:
HeaderService h = new HeaderService();
AuthHeader myHeader = new AuthHeader();
myHeader.Username = "JohnDoe";
myHeader.Password = "password";
h.AuthHeader = myHeader;
String result = h.SecureMethod();
Dim h As New HeaderService
Dim myHeader As New AuthHeader
myHeader.Username = "JohnDoe"
myHeader.Password = "password"
h.AuthHeader = myHeader
Dim result As String = h.SecureMethod()
var h:HeaderService = new HeaderService();
var myHeader:AuthHeader = new AuthHeader();
myHeader.Username = "JohnDoe";
myHeader.Password = "password";
h.AuthHeader = myHeader;
var result:String = h.SecureMethod();
|
| C# |
VB |
JScript |
|
若要查看此代码的运行情况,请运行下面的示例:
- 使用 Windows 身份验证保证服务器上的 XML Web 服务安全性遵从与为 .aspx 页描述的完全相同的模型。
- 还可以通过编程来设置 Windows 凭据,使用 WebService 代理类上的 Username 和 Password 属性。
- 最后,可以自定义身份验证,将凭据信息作为 SOAPHeaders 并连同 SOAP 请求一起传递给需要它的方法。