WCF +用户凭据

时间:2009-07-18 00:21:11

标签: wcf silverlight-3.0 passwords credentials

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

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

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

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

谢谢!

3 个答案:

答案 0 :(得分: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。

答案 1 :(得分: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中的一个重要主题,并且有很多很多选项 - 它可能有点令人生畏,但最后,通常它确实有意义! : - )

马克

答案 2 :(得分:0)

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