2009-03-14 9 views
13

Tengo una aplicación cliente-servidor simple basada en TcpClient/TcpListener y SslStream. Los clientes pueden autenticarse en el servidor utilizando un Certificado X509 o enviando un nombre de usuario y contraseña después de que se haya establecido el SslStream.Cómo usar System.IdentityModel en la propia aplicación cliente-servidor

WCF hace uso de la System.IdentityModel espacio de nombres para los propósitos de autenticación, pero apparently que se puede utilizar en aplicaciones arbitrarias - que suena interesante. Sin embargo, la información sobre cómo hacer esto es escasa (o mi Google Foo es débil hoy).

Entonces, mi pregunta es: ¿Qué debo hacer para integrar System.IdentityModel con mi aplicación? No estoy seguro de si necesito todo ese material de ClaimSet, pero sería bueno si los usuarios pudieran iniciar sesión simplemente usando su cuenta de Windows o cualquier otro mecanismo de autenticación proporcionado. (Desafortunadamente no puedo cambiar a WCF sino que tengo que usar el protocolo personalizado, aunque puedo hacer algunos cambios si es necesario).

Respuesta

17

Mi Google foo era de hecho débil. La respuesta está justo detrás del enlace en mi pregunta. Así que aquí hay un par de enlaces a this blog en caso de que alguien tenga la misma pregunta con el tiempo.

En primer lugar, usted debe tratar de entender "que dicen cosas de ajuste":

Entonces, es necesario saber de dónde proceden de conjuntos de notificaciones:

Armado con este conocimiento, lo que realmente se hace muy sencillo.

Si he entendido bien, el flujo de trabajo básico sería algo como esto:

  1. cliente crea un SecurityToken utilizando un cliente SecurityTokenProvider
  2. serializa el SecurityToken usando un servidor SecurityTokenSerializer
  3. deserializa el SecurityToken usando a SecurityTokenSerializer
  4. El servidor crea IAuthorizationPolicy s usando SecurityTokenAuthenticator
  5. Server crea AuthorizationContext de IAuthorizationPolicy s
  6. Hecho

Ejemplo:

// Create the SecurityTokenProvider 
var p = new UserNameSecurityTokenProvider("username", "password"); 

// Get the SecurityToken from the SecurityTokenProvider 
var t = p.GetToken(TimeSpan.FromSeconds(1.0)) as UserNameSecurityToken; 

// ... transmit SecurityToken to server ... 

// Create the SecurityTokenAuthenticator 
var a = new CustomUserNameSecurityTokenAuthenticator(
    UserNamePasswordValidator.None); 

// Create IAuthorizationPolicies from SecurityToken 
var i = a.ValidateToken(t); 

// Create AuthorizationContext from IAuthorizationPolicies 
var c = AuthorizationContext.CreateDefaultAuthorizationContext(i); 
ShowClaims(c.ClaimSets); 

Para X509SecurityToken s utilizan un X509SecurityTokenProvider/Authenticator. Para WindowsSecurityToken s hay un WindowsSecurityTokenAuthenticator pero no es un proveedor; En su lugar, utilice el WindowsSecurityToken constructor:

var t = new WindowsSecurityToken(WindowsIdentity.GetCurrent()); 

Esto funciona bastante bien. Lo único que omití hasta ahora es la serialización de tokens. Hay una clase SecurityTokenSerializer que tiene una implementación en .NET framework: la clase WSSecurityTokenSerializer que viene con WCF.

Serialización UserNameSecurityToken s y s X509SecurityToken funciona de maravilla (no han tratado deserialización), pero WindowsSecurityToken s aparentemente no son compatibles con el serializador. Esto me deja con los dos métodos de autenticación que ya tengo (certificados y nombre de usuario/contraseña) y, como no quería ese AuthorizationContext de todos modos, me quedaré con lo que tengo :)

+1

En caso de que alguien esté interesado, no estoy seguro de que SecurityToken deba crearse en el lado del cliente y transmitirse a un servidor. Para la seguridad X.509, tiene mucho más sentido iniciar un SslStream con el servidor y crear el X509SecurityToken a partir del certificado del servidor; para la seguridad de Windows, se puede crear WindowsSecurityToken a partir de negotiateStream.RemoteIdentity si se utiliza un NegotiateStream. Para la seguridad de nombre de usuario/contraseña, por supuesto, el nombre de usuario y la contraseña deberán transmitirse. – dtb

7

No tengo la reputación de publicar un comentario en la solución existente, pero me gustaría publicar las nuevas URL en los blogs que figuran en la solución, ya que ya no funcionan. Si alguien puede cambiar esto a un comentario, estaría muy agradecido.

+1

He editado la respuesta de @dtb anterior para reflejar los enlaces fijos.Debería aparecer tan pronto como sea revisado por pares. ¡Gracias! –

+0

A partir de septiembre de 2016 algunos de los enlaces están rotos – JPK

Cuestiones relacionadas