如何在类上使用[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
属性?
我正在寻找一些限制对象访问的方法 即 如果在服务方法中访问某个对象,并且如果用户有权访问服务方法但没有访问该对象的权限,则应抛出异常
答案 0 :(得分:5)
PrincipalPermission
属性可以装饰方法或类。因此,可以限制对对象实例的访问。有几件事需要做:
Windows
指定为客户端凭据类型。PrincipalPermission
属性的机密信息。如果需要将单例实例传递给ServiceHost
构造函数,请执行以下操作:
Thread.CurrentPrincipal
必须具有访问机密对象所需的权限。ServiceHost
实例。 InstanceContextMode
属性的ServiceBehavior
属性必须设置为InstanceContextMode.Single
。否则:
ServiceHost
实例。可选地,使用FaultContract
属性装饰服务方法并从中抛出FaultException
,以避免错误地发送客户端通道。
以下是一个例子:
服务配置文件:
<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 );
}
}
}
答案 1 :(得分:1)
如果您熟悉.NET权限编码(命令式或声明式),则模式完全相同。在声明形式中,PrincipalPermissionAttribute应用于实现服务契约的类中的方法:
[PrincipalPermission(SecurityAction.Demand, Role = "Updaters")]
public bool Update()
{
return true;
}
在此示例中,检查当前主体以查看它是否属于名为Updaters的角色。在属性的实际实现中,调用主体上的IsInRole方法。
对于PrincipalPermissionAttribute的命令性确定,将创建PrincipalPermission类的实例。 PrincipalPermission的构造函数将用户名和角色作为参数。实例化时,可以调用Demand方法来确定当前主体是否具有必要的权限。以下代码提供了一个示例:
PrincipalPermission p = new PrincipalPermission(null, "Updaters");
p.Demand();
配置应如下所示:
<behaviors>
<serviceBehaviors>
<behavior>
...
<serviceAuthorization principalPermissionMode="UseWindowsGroups" />
</behavior>
</serviceBehaviors>
</behaviors>
对于工作样本,请查看:Authorizing Access to Service Operations