PrincipalPermissionMode Enumerazione
Definizione
Importante
Alcune informazioni sono relative alla release non definitiva del prodotto, che potrebbe subire modifiche significative prima della release definitiva. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Imposta la modalità per i controlli delle autorizzazioni quando si utilizza la classe PrincipalPermissionAttribute per controllare l'accesso a un metodo.
public enum class PrincipalPermissionMode
public enum PrincipalPermissionMode
type PrincipalPermissionMode =
Public Enum PrincipalPermissionMode
- Ereditarietà
Campi
Always | 4 | Consente sempre all'utente di specificare una classe IPrincipal per CurrentPrincipal. |
Custom | 3 | Consente all'utente di specificare una classe IPrincipal personalizzata per la proprietà CurrentPrincipal. |
None | 0 | La proprietà CurrentPrincipal non è impostata. |
UseAspNetRoles | 2 | CurrentPrincipal è impostato in base al provider di ruoli ASP.NET (RoleProvider). |
UseWindowsGroups | 1 | La proprietà CurrentPrincipal viene impostata in base a Windows (WindowsPrincipal). Se l'identità dell'utente non è associata a un account di Windows, viene utilizzata l'identità anonima di Windows. |
Esempio
Nell'esempio seguente viene illustrato come specificare UseAspNetRoles.
namespace TestPrincipalPermission
{
class PrincipalPermissionModeWindows
{
[ServiceContract]
interface ISecureService
{
[OperationContract]
string Method1();
}
class SecureService : ISecureService
{
[PrincipalPermission(SecurityAction.Demand, Role = "everyone")]
public string Method1()
{
return String.Format("Hello, \"{0}\"", Thread.CurrentPrincipal.Identity.Name);
}
}
public void Run()
{
Uri serviceUri = new Uri(@"http://localhost:8006/Service");
ServiceHost service = new ServiceHost(typeof(SecureService));
service.AddServiceEndpoint(typeof(ISecureService), GetBinding(), serviceUri);
service.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.UseAspNetRoles;
service.Open();
EndpointAddress sr = new EndpointAddress(
serviceUri, EndpointIdentity.CreateUpnIdentity(WindowsIdentity.GetCurrent().Name));
ChannelFactory<ISecureService> cf = new ChannelFactory<ISecureService>(GetBinding(), sr);
ISecureService client = cf.CreateChannel();
Console.WriteLine("Client received response from Method1: {0}", client.Method1());
((IChannel)client).Close();
Console.ReadLine();
service.Close();
}
public static Binding GetBinding()
{
WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message);
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
return binding;
}
}
}
Namespace TestPrincipalPermission
Friend Class PrincipalPermissionModeWindows
<ServiceContract> _
Private Interface ISecureService
<OperationContract> _
Function Method1() As String
End Interface
Private Class SecureService
Implements ISecureService
<PrincipalPermission(SecurityAction.Demand, Role:="everyone")> _
Public Function Method1() As String Implements ISecureService.Method1
Return String.Format("Hello, ""{0}""", Thread.CurrentPrincipal.Identity.Name)
End Function
End Class
Public Sub Run()
Dim serviceUri As New Uri("http://localhost:8006/Service")
Dim service As New ServiceHost(GetType(SecureService))
service.AddServiceEndpoint(GetType(ISecureService), GetBinding(), serviceUri)
service.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.UseAspNetRoles
service.Open()
Dim sr As New EndpointAddress(serviceUri, EndpointIdentity.CreateUpnIdentity(WindowsIdentity.GetCurrent().Name))
Dim cf As New ChannelFactory(Of ISecureService)(GetBinding(), sr)
Dim client As ISecureService = cf.CreateChannel()
Console.WriteLine("Client received response from Method1: {0}", client.Method1())
CType(client, IChannel).Close()
Console.ReadLine()
service.Close()
End Sub
Public Shared Function GetBinding() As Binding
Dim binding As New WSHttpBinding(SecurityMode.Message)
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows
Return binding
End Function
End Class
End Namespace
Nell'esempio seguente viene illustrato come specificare Personalizzato.
namespace CustomMode
{
public class Test
{
public static void Main()
{
try
{
ShowPrincipalPermissionModeCustom ppwm = new ShowPrincipalPermissionModeCustom();
ppwm.Run();
}
catch (Exception exc)
{
Console.WriteLine("Error: {0}", exc.Message);
Console.ReadLine();
}
}
}
class ShowPrincipalPermissionModeCustom
{
[ServiceContract]
interface ISecureService
{
[OperationContract]
string Method1(string request);
}
[ServiceBehavior]
class SecureService : ISecureService
{
[PrincipalPermission(SecurityAction.Demand, Role = "everyone")]
public string Method1(string request)
{
return String.Format("Hello, \"{0}\"", Thread.CurrentPrincipal.Identity.Name);
}
}
public void Run()
{
Uri serviceUri = new Uri(@"http://localhost:8006/Service");
ServiceHost service = new ServiceHost(typeof(SecureService));
service.AddServiceEndpoint(typeof(ISecureService), GetBinding(), serviceUri);
List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>();
policies.Add(new CustomAuthorizationPolicy());
service.Authorization.ExternalAuthorizationPolicies = policies.AsReadOnly();
service.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom;
service.Open();
EndpointAddress sr = new EndpointAddress(
serviceUri, EndpointIdentity.CreateUpnIdentity(WindowsIdentity.GetCurrent().Name));
ChannelFactory<ISecureService> cf = new ChannelFactory<ISecureService>(GetBinding(), sr);
ISecureService client = cf.CreateChannel();
Console.WriteLine("Client received response from Method1: {0}", client.Method1("hello"));
((IChannel)client).Close();
Console.ReadLine();
service.Close();
}
public static Binding GetBinding()
{
WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message);
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
return binding;
}
class CustomAuthorizationPolicy : IAuthorizationPolicy
{
string id = Guid.NewGuid().ToString();
public string Id
{
get { return this.id; }
}
public ClaimSet Issuer
{
get { return ClaimSet.System; }
}
public bool Evaluate(EvaluationContext context, ref object state)
{
object obj;
if (!context.Properties.TryGetValue("Identities", out obj))
return false;
IList<IIdentity> identities = obj as IList<IIdentity>;
if (obj == null || identities.Count <= 0)
return false;
context.Properties["Principal"] = new CustomPrincipal(identities[0]);
return true;
}
}
class CustomPrincipal : IPrincipal
{
IIdentity identity;
public CustomPrincipal(IIdentity identity)
{
this.identity = identity;
}
public IIdentity Identity
{
get { return this.identity; }
}
public bool IsInRole(string role)
{
return true;
}
}
}
}
Namespace CustomMode
Public Class Test
Public Shared Sub Main()
Try
Dim ppwm As New ShowPrincipalPermissionModeCustom()
ppwm.Run()
Catch exc As Exception
Console.WriteLine("Error: {0}", exc.Message)
Console.ReadLine()
End Try
End Sub
End Class
Friend Class ShowPrincipalPermissionModeCustom
<ServiceContract> _
Private Interface ISecureService
<OperationContract> _
Function Method1(ByVal request As String) As String
End Interface
<ServiceBehavior> _
Private Class SecureService
Implements ISecureService
<PrincipalPermission(SecurityAction.Demand, Role:="everyone")> _
Public Function Method1(ByVal request As String) As String Implements ISecureService.Method1
Return String.Format("Hello, ""{0}""", Thread.CurrentPrincipal.Identity.Name)
End Function
End Class
Public Sub Run()
Dim serviceUri As New Uri("http://localhost:8006/Service")
Dim service As New ServiceHost(GetType(SecureService))
service.AddServiceEndpoint(GetType(ISecureService), GetBinding(), serviceUri)
Dim policies As New List(Of IAuthorizationPolicy)()
policies.Add(New CustomAuthorizationPolicy())
service.Authorization.ExternalAuthorizationPolicies = policies.AsReadOnly()
service.Authorization.PrincipalPermissionMode = PrincipalPermissionMode.Custom
service.Open()
Dim sr As New EndpointAddress(serviceUri, EndpointIdentity.CreateUpnIdentity(WindowsIdentity.GetCurrent().Name))
Dim cf As New ChannelFactory(Of ISecureService)(GetBinding(), sr)
Dim client As ISecureService = cf.CreateChannel()
Console.WriteLine("Client received response from Method1: {0}", client.Method1("hello"))
CType(client, IChannel).Close()
Console.ReadLine()
service.Close()
End Sub
Public Shared Function GetBinding() As Binding
Dim binding As New WSHttpBinding(SecurityMode.Message)
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows
Return binding
End Function
Private Class CustomAuthorizationPolicy
Implements IAuthorizationPolicy
Private id_Renamed As String = Guid.NewGuid().ToString()
Public ReadOnly Property Id() As String Implements System.IdentityModel.Policy.IAuthorizationComponent.Id
Get
Return Me.id_Renamed
End Get
End Property
Public ReadOnly Property Issuer() As ClaimSet Implements IAuthorizationPolicy.Issuer
Get
Return ClaimSet.System
End Get
End Property
Public Function Evaluate(ByVal context As EvaluationContext, ByRef state As Object) As Boolean Implements IAuthorizationPolicy.Evaluate
Dim obj As Object = Nothing
If (Not context.Properties.TryGetValue("Identities", obj)) Then
Return False
End If
Dim identities As IList(Of IIdentity) = TryCast(obj, IList(Of IIdentity))
If obj Is Nothing OrElse identities.Count <= 0 Then
Return False
End If
context.Properties("Principal") = New CustomPrincipal(identities(0))
Return True
End Function
End Class
Private Class CustomPrincipal
Implements IPrincipal
Private identity_Renamed As IIdentity
Public Sub New(ByVal identity As IIdentity)
Me.identity_Renamed = identity
End Sub
Public ReadOnly Property Identity() As IIdentity Implements IPrincipal.Identity
Get
Return Me.identity_Renamed
End Get
End Property
Public Function IsInRole(ByVal role As String) As Boolean Implements IPrincipal.IsInRole
Return True
End Function
End Class
End Class
End Namespace
Commenti
Quando viene applicata la classe PrincipalPermissionAttribute a un metodo, la presente modalità specifica quale set di ruoli utilizzare per l'autorizzazione dell'accesso. Per impostazione predefinita, l'attributo utilizza gruppi di Windows (ad esempio Administrator
o Users
) per specificare il ruolo al quale è necessario che appartenga l'utente.
Per impostare la modalità a livello di programmazione, creare un'istanza della classe ServiceHost
, quindi individuare la classe ServiceAuthorizationBehavior nella raccolta dei comportamenti corrispondente e impostare la proprietà PrincipalPermissionMode sull'enumerazione appropriata. Nell'esempio seguente viene impostata la proprietà su UseAspNetRoles.
ServiceHost myServiceHost = new ServiceHost(typeof(Calculator), baseUri);
ServiceAuthorizationBehavior myServiceBehavior =
myServiceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
myServiceBehavior.PrincipalPermissionMode =
PrincipalPermissionMode.UseAspNetRoles;
Dim myServiceHost As New ServiceHost(GetType(Calculator), baseUri)
Dim myServiceBehavior As ServiceAuthorizationBehavior = myServiceHost.Description.Behaviors.Find(Of ServiceAuthorizationBehavior)()
myServiceBehavior.PrincipalPermissionMode = PrincipalPermissionMode.UseAspNetRoles
È anche possibile impostare il comportamento nella configurazione aggiungendo un <serviceAuthorization> al <servizioBehaviors> di un file di configurazione, come illustrato nel codice seguente.
// Only a client authenticated with a valid certificate that has the
// specified subject name and thumbprint can call this method.
[PrincipalPermission(SecurityAction.Demand,
Name = "CN=ReplaceWithSubjectName; 123456712345677E8E230FDE624F841B1CE9D41E")]
public double Multiply(double a, double b)
{
return a * b;
}
' Only a client authenticated with a valid certificate that has the
' specified subject name and thumbprint can call this method.
<PrincipalPermission(SecurityAction.Demand, Name := "CN=ReplaceWithSubjectName; 123456712345677E8E230FDE624F841B1CE9D41E")> _
Public Function Multiply(ByVal a As Double, ByVal b As Double) As Double
Return a * b
End Function
L'enumerazione influisce su come l'attributo PrincipalPermissionAttribute assegna l'autorizzazione a un utente quando viene applicato a un metodo. L'esempio seguente applica l'attributo a un metodo e richiede che l'utente appartenga al gruppo Users del computer. Questo codice funziona solo se la proprietà PrincipalPermissionMode è impostata su UseWindowsGroup
(impostazione predefinita).
// Only members of the CalculatorClients group can call this method.
[PrincipalPermission(SecurityAction.Demand, Role = "Users")]
public double Add(double a, double b)
{
return a + b;
}
' Only members of the CalculatorClients group can call this method.
<PrincipalPermission(SecurityAction.Demand, Role := "Users")> _
Public Function Add(ByVal a As Double, ByVal b As Double) As Double
Return a + b
End Function
UseAspNetRoles
Il valore UseAspNetRoles viene usato per tutti i tipi di credenziali. Questa modalità consente a Windows Communication Foundation (WCF) di usare il provider di ruoli ASP.NET per prendere decisioni di autorizzazione.
Quando la credenziale di un servizio è un certificato X.509, è possibile impostare la proprietà Name
della classe PrincipalPermissionAttribute su una stringa che è costituita dai valori concatenati del campo Oggetto e del campo Identificazione digitale, come illustrato nell'esempio seguente.
ServiceHost myServiceHost = new ServiceHost(typeof(Calculator), baseUri);
ServiceAuthorizationBehavior myServiceBehavior =
myServiceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
myServiceBehavior.PrincipalPermissionMode =
PrincipalPermissionMode.UseAspNetRoles;
MyServiceAuthorizationManager sm = new MyServiceAuthorizationManager();
myServiceBehavior.ServiceAuthorizationManager = sm;
Dim myServiceHost As New ServiceHost(GetType(Calculator), baseUri)
Dim myServiceBehavior As ServiceAuthorizationBehavior = myServiceHost.Description.Behaviors.Find(Of ServiceAuthorizationBehavior)()
myServiceBehavior.PrincipalPermissionMode = PrincipalPermissionMode.UseAspNetRoles
Dim sm As New MyServiceAuthorizationManager()
myServiceBehavior.ServiceAuthorizationManager = sm
La stringa concatenata è costituita dai valori dell'oggetto e dell'identificazione digitale separati da un punto e virgola e da uno spazio.
È inoltre possibile il campo Oggetto di un certificato sia impostato su una stringa vuota. In questo caso, è possibile impostare la proprietà Name
su un punto e virgola seguito da un spazio e quindi dall'identificazione digitale, come illustrato nell'esempio seguente.
// Only a client authenticated with a valid certificate that has the
// specified thumbprint can call this method.
[PrincipalPermission(SecurityAction.Demand,
Name = "; 123456712345677E8E230FDE624F841B1CE9D41E")]
public double Divide(double a, double b)
{
return a * b;
}
' Only a client authenticated with a valid certificate that has the
' specified thumbprint can call this method.
<PrincipalPermission(SecurityAction.Demand, Name := "; 123456712345677E8E230FDE624F841B1CE9D41E")> _
Public Function Divide(ByVal a As Double, ByVal b As Double) As Double
Return a * b
End Function
Se un provider di ruoli ASP.NET è presente, è inoltre possibile impostare la proprietà Role su un ruolo nel database. Per impostazione predefinita, il database è rappresentato dalla classe SqlRoleProvider. È inoltre possibile impostare un provider di ruoli personalizzato con la proprietà RoleProvider della classe ServiceAuthorizationBehavior. Il codice seguente consente di impostare il ruolo su Administrators
. Si noti che è necessario che il provider di ruoli esegua il mapping dell'account utente a quel ruolo.
[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
public string ReadFile(string fileName)
{
// Code not shown.
return "Not implemented";
}
<PrincipalPermission(SecurityAction.Demand, Role := "Administrators")> _
Public Function ReadFile(ByVal fileName As String) As String
' Code not shown.
Return "Not implemented"
End Function
Per altre informazioni sull'uso di WCF e del provider di ruoli, vedere Procedura: Usare il provider di ruoli ASP.NET con un servizio.
Personalizzato
Quando la proprietà è impostata su Custom, è necessario specificare anche una classe personalizzata che implementa la IAuthorizationPolicy classe. Questa classe ha lo scopo di fornire la rappresentazione del chiamante IPrincipal
all'interno della raccolta Properties. È necessario che l'istanza IPrincipal
venga memorizzata nella raccolta delle proprietà utilizzando la chiave stringa "Principal", come illustrato nell'esempio seguente.
evaluationContext.Properties["Principal"]=new CustomPrincipal(identity);
Background
La sicurezza basata sul ruolo in .NET Framework consente alle applicazioni di specificare le autorizzazioni tramite codice. Specificando la richiesta PrincipalPermission, la proprietà CurrentPrincipal deve soddisfare il requisito PrincipalPermission
. Ad esempio, è necessario che l'utente faccia parte di un ruolo o un gruppo specifico In caso contrario, il thread non viene autorizzato a eseguire il codice e viene generata un'eccezione. WCF fornisce un set di PrincipalPermissionMode selezioni per specificare la CurrentPrincipal base di SecurityContext conseguenza.