He realizado varios demos con MSE mostrando las ventajas que podemos tener al virtualizar fácilmente los servicios y administrarlos con políticas como las que vienen con la Guía de Seguridad, la que me ilustro en el proceso fue SqlProviderSecurity, esta política nos permite tener una autenticación al servicio WCF por medio de un usuario y contraseña, este usuario se autenticaría en la base de datos aspnetdb la cual refleja el modelo Membership, así mismo para la autorización se extraen los roles configurados en esta base de datos.
Adicional a esta podemos validar que roles pueden acceder a las operaciones expuestas en todos los endpoint para esto usamos RoleProviderAuthorization.
Bueno como ya había colocado el post en codeplex, donde veíamos que este ejemplo era bueno el mundo real era otro, la mayoría teníamos que validar y autenticar con usuarios Windows!!
Es por eso que investigue el código de la Guía e Implemente un Windows Role Provider Authorization.
Lo primero que tenemos que tener en cuenta es que no cree una política que me permitir autenticar en Windows, ya que esto lo hace cualquier binding de MSE que tenga las características clientCredentialType=”Windows”, ya con esto el usuario envía su identificación (el usuario ya se autentico). Lo que desarrolle fue la validación de roles de usuario para las operaciones permitidas, estas fueron las nuevas clases implementadas:
Clases Nuevas:
- Microsoft.MSE.Behaviors.Security.Configuration.WindowsRoleProviderAuthorizationElement
- Microsoft.MSE.Behaviors.Security.WindowsRoleProviderAuthorizationBehavior.cs
- Microsoft.MSE.Behaviors.Security.WindowsRoleProviderAuthorizationParameterInspector.cs
- Microsoft.MSE.Behaviors.Security.WindowsRoleProviderServiceAuthorizationManager.cs
- Microsoft.MSE.PolicyDesigners.Security.WindowsRoleAuthzAssertionUI.xaml
La implementacion importante fue para la clase WindowsRoleProviderServiceAuthorizationManager
1. Las operaciones en MSE 7.5.29 ahora tienen una nueva propiedad llamada Action, esta nos permiten tener un mismo nombre de operacion con Action diferentes, debido a eso comentarie esta linea en la clase
//I comment the action because we can have many //Operations with the same Name for diferents //endpoints. With MSE 7.5.29.0 we can differ the operations by the action //action = action.IndexOf(':') > 0 ? action.Substring(0, action.IndexOf(':'))
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
2. Y He aquí las línea que use para obtener roles, acordémonos que no utilizo provider porque vamos a obtener los roles del token de Windows, esta forma de hacerla me gusta debido a que el rendimiento es alto comparado con otros métodos como ir al LDAP a traer información
string[] userRoles = GetRoles(operationContext.ServiceSecurityContext.WindowsIdentity);
NOTA: en el código que adjunto imprimí en Debug los Grupos de Dominio y de Equipo que tiene el usuario, eliminar esta línea y todas la que tenga Trace del código para producción
private static string[] GetRoles(WindowsIdentity id) { List<string> groups = new List<string>(); IdentityReferenceCollection IRC = id.Groups.Translate(typeof(NTAccount)); foreach (NTAccount acc in IRC) { groups.Add(acc.Value); System.Diagnostics.Trace.WriteLine("Grupo de Windows: "+ acc.Value); } return groups.ToArray(); }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Después de la compilación va la instalaciones de la Guía de Seguridad con el nuevo assertion:
Ya podemos visualizar aquí nuestro nuevo WindowsRoleProviderAuthorization Assertion
Podemos configurar Los Grupos del Equipo y sobretodo del dominio para asociar que operaciones tiene permiso de ejecución
Aquí tengo un binding que usa Tipo de Autenticación Windows, estos los debemos usar para que nuestra política funcione
O podemos usar el binding NetTCP del MSE
<bindings xmlns=""> <netTcpBinding> <binding name="netTcp" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions" hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"> </readerQuotas> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"> </reliableSession> <security mode="Transport"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"> </transport> <message clientCredentialType="Windows"> </message> </security> </binding> </netTcpBinding> </bindings>
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Aquí pueden descargar el codigo fuente: Microsoft.MSE.SecurityGuide_With_WindowsRoleProviderAuthorization
Leave a Reply