wcf数据合同授权
如何在类上使用wcf数据合同授权,wcf,authentication,authorization,Wcf,Authentication,Authorization,如何在类上使用[PrincipalPermission(SecurityAction.Demand,Role=“Administrators”)]属性 我正在寻找某种方法来限制对我的对象的访问 即 如果在服务方法中访问某个对象,并且如果用户有权访问该服务方法,但没有访问该对象的权限,则应引发异常。如果您熟悉.NET权限编码(命令式或声明式),则模式完全相同。在声明形式中,PrincipalPermissionAttribute应用于实现服务契约的类中的方法: [PrincipalPermissi
[PrincipalPermission(SecurityAction.Demand,Role=“Administrators”)]
属性
我正在寻找某种方法来限制对我的对象的访问
即
如果在服务方法中访问某个对象,并且如果用户有权访问该服务方法,但没有访问该对象的权限,则应引发异常。如果您熟悉.NET权限编码(命令式或声明式),则模式完全相同。在声明形式中,PrincipalPermissionAttribute应用于实现服务契约的类中的方法:
[PrincipalPermission(SecurityAction.Demand, Role = "Updaters")]
public bool Update()
{
return true;
}
在本例中,将检查当前主体是否属于名为Updaters的角色。在属性的实际实现中,将调用主体上的IsInRole方法
为了强制确定PrincipalPermission属性,将创建PrincipalPermission类的实例。PrincipalPermission的构造函数将用户名和角色作为参数。实例化时,可以调用Demand方法来确定当前主体是否具有必要的权限。以下代码提供了一个示例:
PrincipalPermission p = new PrincipalPermission(null, "Updaters");
p.Demand();
配置应如下所示:
<behaviors>
<serviceBehaviors>
<behavior>
...
<serviceAuthorization principalPermissionMode="UseWindowsGroups" />
</behavior>
</serviceBehaviors>
</behaviors>
...
有关工作示例,请参阅:
PrincipalPermission
属性可以修饰方法或类。因此,可以限制对对象实例的访问。需要做几件事:
Windows
指定为客户端凭据类型PrincipalPermission
属性的机密信息ServiceHost
构造函数,请执行以下操作:
ServiceHost
实例。ServiceBehavior
属性的属性InstanceContextMode
必须设置为InstanceContextMode.Single
ServiceHost
实例FaultContract
属性修饰服务方法,并从中抛出FaultException
,以避免对客户端通道造成故障
以下是一个例子:
PrincipalPermission p = new PrincipalPermission(null, "Updaters");
p.Demand();
服务配置文件:
<system.serviceModel>
<services>
<service name="Server.Service" behaviorConfiguration="Authorization">
<endpoint address=""
binding="netTcpBinding" bindingConfiguration="TCP"
contract="Common.IService" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:13031/Service"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="TCP" openTimeout="00:30:00" closeTimeout="00:00:10" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="Authorization">
<serviceAuthorization principalPermissionMode="UseWindowsGroups" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.serviceModel>
<client>
<endpoint name="NetTcpBinding_IService"
address="net.tcp://localhost:13031/Service"
binding="netTcpBinding" bindingConfiguration="TCP"
contract="Common.IService" />
</client>
<bindings>
<netTcpBinding>
<binding name="TCP" openTimeout="00:30:00" closeTimeout="00:00:10" sendTimeout="00:30:00" receiveTimeout="00:30:00" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
[PrincipalPermission(SecurityAction.Demand, Role = "Administrators" ) ]
public class ContactInfo
{
public string FirstName { get; set; }
public string LastName { get; set; }
public ContactInfo()
{
FirstName = "John";
LastName = "Doe";
}
public override string ToString()
{
return string.Format( "{0} {1}", FirstName, LastName );
}
}
[ServiceContract]
public interface IService
{
[OperationContract]
[FaultContract( typeof( string ) )]
string GetName( int id );
}
[ServiceBehavior]
// Use following if singleton instance needs to be passed to `ServiceHost` constructor
//[ServiceBehavior( InstanceContextMode = InstanceContextMode.Single )]
public class Service : IService
{
private Dictionary<int, ContactInfo> Contacts { get; set; }
public Service()
{
Contacts = new Dictionary<int, ContactInfo>();
IPrincipal originalPrincipal = Thread.CurrentPrincipal;
try
{
Thread.CurrentPrincipal = new WindowsPrincipal( WindowsIdentity.GetCurrent() );
Contacts.Add( 1, new ContactInfo() );
}
finally
{
Thread.CurrentPrincipal = originalPrincipal;
}
}
public string GetName( int id )
{
if ( Contacts.Count < id )
return null;
try
{
return Contacts[ id ].ToString();
}
catch ( Exception ex )
{
throw new FaultException<string>( ex.Message );
}
}
}
服务合同及其实施:
<system.serviceModel>
<services>
<service name="Server.Service" behaviorConfiguration="Authorization">
<endpoint address=""
binding="netTcpBinding" bindingConfiguration="TCP"
contract="Common.IService" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:13031/Service"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="TCP" openTimeout="00:30:00" closeTimeout="00:00:10" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="Authorization">
<serviceAuthorization principalPermissionMode="UseWindowsGroups" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.serviceModel>
<client>
<endpoint name="NetTcpBinding_IService"
address="net.tcp://localhost:13031/Service"
binding="netTcpBinding" bindingConfiguration="TCP"
contract="Common.IService" />
</client>
<bindings>
<netTcpBinding>
<binding name="TCP" openTimeout="00:30:00" closeTimeout="00:00:10" sendTimeout="00:30:00" receiveTimeout="00:30:00" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
[PrincipalPermission(SecurityAction.Demand, Role = "Administrators" ) ]
public class ContactInfo
{
public string FirstName { get; set; }
public string LastName { get; set; }
public ContactInfo()
{
FirstName = "John";
LastName = "Doe";
}
public override string ToString()
{
return string.Format( "{0} {1}", FirstName, LastName );
}
}
[ServiceContract]
public interface IService
{
[OperationContract]
[FaultContract( typeof( string ) )]
string GetName( int id );
}
[ServiceBehavior]
// Use following if singleton instance needs to be passed to `ServiceHost` constructor
//[ServiceBehavior( InstanceContextMode = InstanceContextMode.Single )]
public class Service : IService
{
private Dictionary<int, ContactInfo> Contacts { get; set; }
public Service()
{
Contacts = new Dictionary<int, ContactInfo>();
IPrincipal originalPrincipal = Thread.CurrentPrincipal;
try
{
Thread.CurrentPrincipal = new WindowsPrincipal( WindowsIdentity.GetCurrent() );
Contacts.Add( 1, new ContactInfo() );
}
finally
{
Thread.CurrentPrincipal = originalPrincipal;
}
}
public string GetName( int id )
{
if ( Contacts.Count < id )
return null;
try
{
return Contacts[ id ].ToString();
}
catch ( Exception ex )
{
throw new FaultException<string>( ex.Message );
}
}
}
[服务合同]
公共接口设备
{
[经营合同]
[FaultContract(类型(字符串))]
字符串GetName(int-id);
}
[服务行为]
//如果需要将单例实例传递给`ServiceHost`构造函数,请使用以下命令
//[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
公共课服务:IService
{
专用字典联系人{get;set;}
公共服务()
{
联系人=新字典();
IPrincipal originalPrincipal=Thread.CurrentPrincipal;
尝试
{
Thread.CurrentPrincipal=新的WindowsPrincipal(WindowsIdentity.GetCurrent());
Contacts.Add(1,newcontactinfo());
}
最后
{
Thread.CurrentPrincipal=originalPrincipal;
}
}
公共字符串GetName(int-id)
{
如果(联系人计数
关于如何构建这样一个系统的任何指导可能重复……您只能根据角色限制调用服务方法。您不能以相同的方式限制对数据的访问。我想模拟windows操作系统文件夹结构。每个用户对每个文件夹都有不同的访问权限,不同的用户可以根据其角色对该文件夹执行不同的操作。您需要的限制是可能的。请参阅我的答案…实例上下文模式与principal permission属性的关系是什么..如果使用每次调用模式,是否会有任何问题..@taher chhabrawala:PerCall
实例上下文模式也可以使用。这是我试图避免多个服务实例的代码的遗留部分(为了将singleton对象传递给ServiceHost
构造函数,服务实现必须使用ServiceBehavior
属性修饰,该属性的InstanceContextMode
设置为InstanceContextMode.Single
)。我会在一分钟内编辑答案。@taher chhabrawala:这对你有用吗?或者你需要更像是返回整个机密对象实例的东西?@Rest…这对我来说很有效…实际上我必须对此进行一些修改…但它确实为我指明了正确的方向…谢谢..我将你的答案标记为:)