5

我正在开发一个 Silverlight v3 Web 应用程序,我想保护对我用来获取数据的 WCF 服务的访问。我目前的 WCF 工作得很好,但它不需要任何用户凭据。

我对 WCF 的这方面不是很有经验,所以我的第一个想法是在我的每个服务操作中添加用户名和密码参数。我遇到的问题是这将需要大量冗余代码,并且用户名和密码将以纯文本形式通过网络传输。

我想要的是一种在创建服务代理后立即在客户端预先指定凭据的方法(我正在使用从“添加服务引用”自动生成的代理)。

在谷歌搜索解决方案时,我只能找到类似于我的第一个想法的解决方案(使用用户名/密码参数)。有人可以指出我正确的方向吗?

谢谢!

4

3 回答 3

7

这些用户名和密码从何而来?如果您的网站已经实现了表单身份验证,那么您可以自己绕过设置凭据并使用表单身份验证 cookie。如果您的用户已登录,则 cookie 将随 Web 服务调用一起传播。为了在另一边阅读它,您需要进行一些更改。

首先,您需要在 system.ServiceModel 部分为 WCF 启用 ASP.NET 兼容模式:

<system.serviceModel>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
</system.serviceModel>

完成后,对于您想要了解 ASP.NET cookie 的每个服务方法,将 [AspNetCompatibilityRequirements] 属性添加到您的服务类

[ServiceContract]
[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ExampleService
{
}

现在,在每个方法中,您都可以访问 HttpContext.Current.User.Identity 对象来发现用户的身份。

如果您只希望经过身份验证的用户调用某些方法,那么您可以使用 PrincipalPermission 因此

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Authenticated=true)]
public string Echo()

作为奖励,如果您使用 ASP.NET 的角色提供程序,那么这些也将被填充,然后您可以在方法上使用 PrincipalPermission 将它们限制为特定角色的成员:

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role="Administators")]
public string NukeTheSiteFromOrbit()

这显然也适用于 Silverlight2。

于 2009-07-18T08:51:06.513 回答
1

不要自己滚动并添加显式参数 - 这确实是太多的工作!

查看 WCF 安全功能 - 大量可用!例如,您可以保护消息并在消息中包含凭据 - 全部开箱即用,无需额外编码!

查看 Michele Leroux Bustamante 撰写的这篇关于 WCF 安全性的优秀文章:http: //www.devx.com/codemag/Article/33342

在您的情况下,我建议使用用户名凭据进行消息安全性 - 您需要在两端进行配置:

服务器端:

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service name="YourService">
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
  </service>
</services>

您需要在客户端应用相同的设置:

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
</client>

现在您的服务器和客户端就安全性达成一致 - 在客户端上,您将指定要使用的用户名和密码,如下所示:

YourServiceClient client = new YourServiceClient();

client.ClientCredentials.UserName.UserName = "your user name";
client.ClientCredentials.UserName.Password = "top$secret";

在服务器端,您需要设置验证这些用户凭据的方式——通常针对 Windows 域 (Active Directory) 或针对 ASP.NET 成员资格提供程序模型。在任何情况下,如果无法针对您定义的商店验证用户凭据,则调用将被拒绝。

希望这会有所帮助 - 安全性是 WCF 中的一个重要主题,并且有很多选择 - 这可能有点令人生畏,但最后,通常它确实是有道理的!:-)

马克

于 2009-07-18T08:32:05.787 回答
0

您可以传入某种身份验证对象并使用 WCF 在消息级别对其进行加密。然后可以使用C# 方面(http://www.postsharp.org/ )来避免冗余逻辑。这是一种非常干净的处理方式。

于 2009-07-18T00:27:50.563 回答