我正在开发一个Silverlight v3 Web应用程序,我想保护访问我用来获取数据的WCF服务。我目前正在使用WCF,但它不需要任何用户凭据。
我对WCF的这方面不太熟悉,所以我的第一个想法是为我的每个服务操作添加用户名和密码参数。我遇到的问题是,这需要大量冗余代码,并且用户名和密码将以纯文本形式通过网络传输。
我想要的是在创建服务代理后立即在客户端指定凭据的方法(我使用从“添加服务引用”自动生成的代理)。
在谷歌搜索解决方案时,我只能找到类似于我的第一个想法的解决方案(使用用户名/密码参数)。有人可以指出我正确的方向吗?
谢谢!
答案 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/)来避免冗余逻辑。它是一种非常干净的处理方式。