type tool open example debugger debug checker .net .net-4.5 wif claims-based-identity

.net - tool - Transformación de reclamaciones simples y almacenamiento en caché con autenticación de Windows



open graph facebook (2)

El objetivo de esta respuesta es proporcionar más aclaraciones sobre la respuesta de John anterior después de experimentar varios días frustrantes al intentar resolver algunos problemas similares.

1. ReclamacionesPrincipalHttpModule

Como descubrió John, si está utilizando Windows Auth o Forms Auth, ASP.NET no invocará automáticamente su ClaimsAuthenticationManager (no es un escenario federado). Debe hacerlo usted mismo después de que ASP.NET haya autenticado al usuario. El uso de ClaimsPrincipalHttpModule, que solía ser parte de IdentityModel, garantizará que esto ocurra.

Sin embargo, tenga cuidado al usar este módulo. Fue removido por una razón. Mi teoría sobre por qué se eliminó de IdentityModel es porque no funciona bien si usted hospeda servicios WCF en su aplicación ASP.NET y tiene aspNetCompatibilityEnabled = true. Esto causará que su autenticación de WCF se rompa (el módulo se ejecutará ANTES de la canalización de WCF y mi experiencia es que sus clientes de WCF ya no podrán autenticarse correctamente, lo he confirmado al usar Windows Auth).

Si está alojando servicios de WCF en este escenario, debe asegurarse de alguna manera de que el Administrador de notificaciones de autenticación solo se invoque para solicitudes que no sean de WCF. Para las solicitudes de WCF, parece que tiene que confiar en la canalización de WCF para hacerlo ( <serviceCredentials useIdentityConfiguration="true" /> ). La solución más sencilla es simplemente desactivar aspNetCompatibilityEnabled. Si esta no es una opción, no debe usar ClaimsPrincipalHttpModule, sino que de alguna manera debe examinar la solicitud entrante y solo invocar el Administrador de autenticación de reclamaciones si la solicitud no está destinada a WCF.

2. Error de manejo seguro (ObjectDisposedException)

Esto ocurre si crea un SessionSecurityToken que se basa en una identidad de Windows. El SessionAuthenticationModule tiene una lógica especial para manejar los reclamos de WindowsIdentity leídos de un SessionSecurityToken e intentará rehidratar el WindowsIdentity usando datos que ya no son válidos. (No estoy seguro de las circunstancias en las que funcionaría, pero falló constantemente en todos los escenarios que probé). Por lo tanto, como explicó John, la lección aquí es que cuando se intenta utilizar WIF con la autenticación de Windows, SessionSecurityTokens no debe crearse desde un WindowsPrincipal (o más correctamente una WindowsIdentity). Cualquier otro tipo de ClaimsPrincipal transformado debe estar bien.

Durante los últimos días he estado leyendo acerca de la base de identidad de Windows y de cómo es tan buena y flexible y está integrada en .net 4.5. A pesar de revisar docenas de apis, publicaciones de blog, instrucciones, etc., no puedo, por mi vida, conseguir que una implementación simple funcione.

Solo estoy usando la autenticación de Windows y puedo obtener el principal y ver los reclamos que vienen con él (que es donde parece que todo ejemplo parece terminar). Sin embargo, quiero transformarlos luego en reclamos útiles y guardar en caché los resultados para que la transformación no ocurra en cada solicitud.

En mi web.config tengo:

<configSections> <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> </configSections> <system.identityModel> <identityConfiguration> <claimsAuthenticationManager type="SecurityProj.MyClaimsTransformationModule,SecurityProj" /> <claimsAuthorizationManager type="SecurityProj.MyClaimsAuthorizationManager,SecurityProj" /> </identityConfiguration> </system.identityModel>

Sin embargo, el administrador de autenticación nunca se llama. La única forma en que puedo hacer que funcione es agregando:

protected void Application_PostAuthenticateRequest() { ClaimsPrincipal currentPrincipal = ClaimsPrincipal.Current; ClaimsTransformationModule customClaimsTransformer = new MyClaimsTransformationModule(); ClaimsPrincipal tranformedClaimsPrincipal = customClaimsTransformer.Authenticate(string.Empty, currentPrincipal); HttpContext.Current.User = tranformedClaimsPrincipal; }

A mi archivo global.asax.cs Funciona en la primera solicitud, pero luego aparece el mensaje de error "Se ha cerrado el manejo seguro" y no tengo idea de qué lo está causando. Claramente, esta no es la forma correcta de hacerlo, entonces, ¿alguien sabe qué es la mejor o simplemente la práctica de trabajo? Esto es solo para la autenticación de Windows, no necesito nada más complicado que eso.

Para el almacenamiento en caché, estaba tratando de usar:

SessionSecurityToken token = FederatedAuthentication.SessionAuthenticationModule .CreateSessionSecurityToken( currentPrincipal, "Security test", System.DateTime.UtcNow, System.DateTime.UtcNow.AddHours(1), true); if (FederatedAuthentication.SessionAuthenticationModule != null && FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(HttpContext.Current.Request.Cookies)) { return; } FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(token);

pero tampoco estoy seguro de esa parte y los problemas de transformación deben solucionarse primero.

Cualquier ayuda sería apreciada. Solo necesita la búsqueda / transformación a llamar y un conjunto de cookies, gracias.


Tengo todo funcionando ahora, así es como lo hice:

En esta página: http://msdn.microsoft.com/en-us/library/ee517293.aspx Fue un párrafo clave:

Si desea que su aplicación RP tenga en cuenta las reclamaciones, pero no tiene un STS (por ejemplo, el RP utiliza la autenticación de formularios o la autenticación integrada de Windows), puede usar el ClaimsPrincipalHttpModule. Este módulo se encuentra en el canal HTTP de su aplicación e intercepta información de autenticación. Genera un IClaimsPrincipal para cada usuario en función del nombre de usuario, la pertenencia a grupos y otra información de autenticación de ese usuario. Se debe insertar ClaimsPrincipalHttpModule al final de la <httpModules> , que es el primer elemento en la sección <modules> de <system.webServer> en IIS 7.

Y esta página:

http://leastprivilege.com/2012/04/04/identity-in-net-4-5part-2-claims-transformation-in-asp-net-beta-1/

Te da toda la clase:

public class ClaimsTransformationHttpModule : IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { context.PostAuthenticateRequest += Context_PostAuthenticateRequest; } void Context_PostAuthenticateRequest(object sender, EventArgs e) { var context = ((HttpApplication)sender).Context; // no need to call transformation if session already exists if (FederatedAuthentication.SessionAuthenticationModule != null && FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(context.Request.Cookies)) { return; } var transformer = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthenticationManager; if (transformer != null) { var transformedPrincipal = transformer.Authenticate(context.Request.RawUrl, context.User as ClaimsPrincipal); context.User = transformedPrincipal; Thread.CurrentPrincipal = transformedPrincipal; } } }

Ahora agregue esa clase al web.config:

<modules> <add name="ClaimsTransformationHttpModule" type="TestSecurity.ClaimsTransformationHttpModule" /> </modules>

Ahora llamará a la transformación y puedo eliminar el método de autenticación posterior en global.asax.

En el método de autenticación, lo llamo para configurar la cookie:

private void CreateSession(ClaimsPrincipal transformedPrincipal) { SessionSecurityToken sessionSecurityToken = new SessionSecurityToken(transformedPrincipal, TimeSpan.FromHours(8)); FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken); }

El módulo de antes ya está configurado para verlo y omitir la autenticación si está presente.

Por último, por el error de manejo seguro que seguí recibiendo. No estoy exactamente seguro de la causa, pero descubrí que si modificaba el principal que se pasa a Autenticar y luego lo devolvía (que es lo que se muestra en msdn), el error se mostraría en todas las solicitudes posteriores. Sin embargo, si he creado y devuelto un nuevo principal, no se producirá. Esto también resulta útil para retirar reclamos que no necesita.

List<Claim> newClaims = new List<Claim>(); var keeper = ((ClaimsIdentity)incomingPrincipal.Identity).Claims.First(c => c.Type == ClaimTypes.Name); newClaims.Add(keeper); ClaimsIdentity ci = new ClaimsIdentity(newClaims, "Negotiate"); return new ClaimsPrincipal(ci);

Así que ahora puedo autenticar Windows, traer notificaciones personalizadas y guardarlas en caché con una cookie. Espero que esto ayude a alguien más a tratar de hacer lo mismo y si no estoy haciendo algo bien, por favor hágamelo saber.