PrincipalPermissionMode Enumeração
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
Define o modo para verificações de autorização ao usar o PrincipalPermissionAttribute para controlar o acesso a um método.
public enum class PrincipalPermissionMode
public enum PrincipalPermissionMode
type PrincipalPermissionMode =
Public Enum PrincipalPermissionMode
- Herança
Campos
Always | 4 | Sempre permite que o usuário especifique uma classe IPrincipal para CurrentPrincipal. |
Custom | 3 | Permite que o usuário especifique uma classe IPrincipal personalizada para CurrentPrincipal. |
None | 0 | CurrentPrincipal não está definido. |
UseAspNetRoles | 2 | CurrentPrincipal é definido com base no provedor de funções de ASP.NET (RoleProvider). |
UseWindowsGroups | 1 | CurrentPrincipal é baseado em conjuntos no Windows (WindowsPrincipal). Se a identidade do usuário não estiver associada uma conta do Windows, o Windows anônimo será usado. |
Exemplos
O exemplo a seguir mostra como especificar 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
O exemplo a seguir mostra como especificar Personalizado.
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
Comentários
Ao aplicar o a um método, esse modo especifica qual conjunto de funções usar ao autorizar o PrincipalPermissionAttribute acesso. Por padrão, o atributo usa grupos do Windows (como Administrator
ou Users
) para especificar a função à qual o usuário deve pertencer.
Para definir o modo programaticamente, crie uma instância da ServiceHost
classe , localize o ServiceAuthorizationBehavior em sua coleção de comportamentos e defina o PrincipalPermissionMode como a enumeração apropriada. O exemplo a seguir define a propriedade como 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
Você também pode definir o comportamento na configuração adicionando um <serviceAuthorization> ao <serviceBehaviors> de um arquivo de configuração, conforme mostrado no código a seguir.
// 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
A enumeração afeta como o PrincipalPermissionAttribute atributo autoriza um usuário quando ele é aplicado a um método. O exemplo a seguir aplica o atributo a um método e exige que o usuário pertença ao grupo Usuários no computador. Esse código funciona somente quando o PrincipalPermissionMode é definido UseWindowsGroup
como (a configuração padrão).
// 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
O valor UseAspNetRoles é usado para todos os tipos de credencial. Esse modo permite que o WCF (Windows Communication Foundation) use o provedor de funções ASP.NET para tomar decisões de autorização.
Quando a credencial de um serviço é um certificado X.509, você pode definir a Name
propriedade do como uma cadeia de PrincipalPermissionAttribute caracteres que consiste nos valores concatenados do campo Assunto e do campo Impressão Digital, conforme mostrado no exemplo a seguir.
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
A cadeia de caracteres concatenada consiste nos valores de assunto e impressão digital separados por um ponto e vírgula e um espaço.
Também é possível que um certificado tenha um campo Subject definido como uma cadeia de caracteres nula. Nesse caso, você pode definir a Name
propriedade como um ponto e vírgula seguido por um espaço e, em seguida, a impressão digital, conforme mostrado no exemplo a seguir.
// 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 um provedor de ASP.NET função estiver presente, você também poderá definir a Role propriedade como uma função no banco de dados. Por padrão, o banco de dados é representado pelo SqlRoleProvider. Você também pode definir um provedor de função personalizado com a RoleProvider propriedade da ServiceAuthorizationBehavior classe . O código a seguir define a função como Administrators
. Observe que o provedor de função deve mapear a conta de usuário para essa função.
[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
Para obter mais informações sobre como usar o WCF e o provedor de função, consulte Como usar o provedor de funções ASP.NET com um serviço.
Personalizado
Quando a propriedade é definida como Personalizado, você também deve fornecer uma classe personalizada que implementa a IAuthorizationPolicy classe . Essa classe é responsável por fornecer a representação do IPrincipal
chamador dentro da Properties coleção. Ele deve armazenar a IPrincipal
instância na coleção de propriedades usando a chave de cadeia de caracteres "Principal", conforme mostrado no exemplo a seguir.
evaluationContext.Properties["Principal"]=new CustomPrincipal(identity);
Tela de fundo
A segurança baseada em função no .NET Framework permite que os aplicativos especifiquem autorizações por meio de código. Ao especificar a PrincipalPermission demanda, o CurrentPrincipal deve atender ao PrincipalPermission
requisito. Por exemplo, que o usuário deve estar em uma função ou grupo específico. Caso contrário, o thread não está autorizado a executar o código, o que resulta em uma exceção. O WCF fornece um conjunto de PrincipalPermissionMode seleções para especificar o CurrentPrincipal com base em SecurityContext adequadamente.