我有一个CCF客户端应用程序正在使用的WCF Web服务。我还在Active Directory中存储了4个组。客户端应用程序正在传递用户凭据以连接此Web服务。
Web服务公开客户端应用程序要访问的多个API或方法,如下所示:
[OperationContract]
bool Read();
[OperationContract]
bool Write();
所有客户都应该可以访问Read()方法
Write()方法只能由属于Active Directory维护的特定Windows用户组的用户访问。
问题: 我们如何根据客户端在AD中维护的用户组来过滤或限制公开的接口或方法?
jrista, 感谢您的回复。我尝试了与PrincipalPermission相同的指令,如下所示:
[PrincipalPermission(SecurityAction.Demand, Role = "Readers")]
[OperationContract]
bool Read();
[PrincipalPermission(SecurityAction.Demand, Role = "Writers")]
[OperationContract]
bool Write();
但它不起作用。读组用户也可以调用Writer()方法,而Writer组用户也可以调用Write()方法。
我想告诉你的一件事是我在web.config文件中使用BasicHttpBind,如下所示:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBind">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="DXDirectory.DXDirectoryService" behaviorConfiguration="DXDirectory.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBind"
name="BasicBinding" contract="DXDirectory.IDXDirectoryService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DXDirectory.Service1Behavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceAuthorization principalPermissionMode="UseWindowsGroups"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
是否需要为此功能实现wsHttpBinding?如果是,那么如何在我的Web服务中实现wsHttpBinding?
答案 0 :(得分:4)
我不确定如何将AD凭据集成到正常的.NET安全框架中。但是,它是可能的(我会看到我是否可以找到一些链接),一旦你这样做,你应该能够使用标准的安全属性来检查一个“角色”,它与你的AD组相对应: / p>
[OperationContract]
bool Read();
[PrincipalPermission(SecurityAction.Demand, Role = "Writers")]
[OperationContract]
bool Write();
要使用AD组,请配置服务行为:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<adServiceBehavior>
<serviceAuthorization principalPermissionMode="UseWindowsGroups" />
</adServiceBehavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
又想到了。有时希望甚至根本不在接口上使用Write()方法。使用WCF,您可以在单个服务类上实现多个服务契约接口。一个理想的解决方案可能是创建两个服务契约接口,一个使用Read()和Write(),一个只使用Read()。根据登录到客户端的用户,您可以对只有读访问权限的用户使用Read()接口,对有权访问这些用户的人使用Read()/ Write()接口。这还允许您向不应具有写访问权限的客户端公开最安全的服务合同,同时在内部使用读/写合同进行管理。您永远不会暴露可能以这种方式被利用的代码。
答案 1 :(得分:4)
jrista是对的 - 您可以使用内置的Windows授权服务(包括“PrincipalPermission”属性)来限制访问。
但是,然后才能进行授权,您需要进行身份验证。首先,在决定是否让他(或她)进入之前,你需要知道谁在敲你的服务门。
为此,您需要确保在邮件交换中使用Windows凭据,并且客户端和服务器必须位于同一域中(或具有相互信任关系的域中)。此外,您需要使用默认情况下允许和支持Windows凭据的绑定,如wsHttp或netTcp,并且您需要确保使用和配置绑定安全配置,该配置将Windows凭据从客户端传输到服务器。
你需要有类似的东西:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="Secured">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
然后您需要从客户端和服务器端点引用该绑定配置。
WsHttpBinding和NetTcpBinding都默认使用Windows客户端凭据,所以开箱即用,除非您完全关闭安全性,否则您应该在这两个绑定中获得Windows凭据支持。
马克
PS:
正如jrista所展示的那样(我之前回答过almost the same question你做过),你真的只需要将PrincipalPermission属性添加到你想要限制属于某个特定组的用户的方法 - 没有手动搞乱需要AD小组成员资格等。
如果您确实必须获取调用您服务的用户所属的群组,则可以查看WindowsIdentity调用的“.Groups”属性:
WindowsIdentity winCaller = ServiceSecurityContext.Current.WindowsIdentity;
foreach(var group in winCaller.Groups)
{
Console.WriteLine(group.Value);
}
如果您需要呼叫用户的姓名,请使用winCaller.Name
。如果您需要用户呼叫的SID,请使用winCaller.User
。它没关系 - 没有混乱,没有复杂的代码 - 只需使用它! : - )
答案 2 :(得分:0)
如果您在IIS中托管服务器设置为允许匿名?
答案 3 :(得分:0)
尝试在服务类中的方法上添加Principalpermission属性,而不是在服务接口中的操作协定上。