¿Por qué mi ClaimsIdentity IsAuthenticated siempre es false (para el filtro de autorización de api web)?


En un proyecto de Web API estoy anulando el proceso de autenticación normal para comprobar tokens en su lugar. El código se ve algo como esto:

if ( true ) // validate the token or whatever here
{
    var claims = new List<Claim>();
    claims.Add( new Claim( ClaimTypes.Name, "MyUser" ) );
    claims.Add( new Claim( ClaimTypes.NameIdentifier, "MyUserID" ) );
    claims.Add( new Claim( ClaimTypes.Role, "MyRole" ) );

    var claimsIdentity = new ClaimsIdentity( claims );

    var principal = new ClaimsPrincipal( new[] { claimsIdentity } );
    Thread.CurrentPrincipal = principal;
    HttpContext.Current.User = principal;
}

Y luego, cuando aplico el atributo [Authorize] a un controlador, no autoriza.

El código de depuración confirma el mismo comportamiento:

// ALWAYS FALSE!
if ( HttpContext.Current.User.Identity.IsAuthenticated ) {
    // do something
}

¿Por qué cree que el usuario no está autenticado a pesar de que he construido una ClaimsIdentity válida y la he asignado al hilo?

Author: explunit, 2013-11-28

2 answers

El problema se debe a un cambio radical en.Net 4.5. Como se explica en este artículo , la simple construcción de una identidad de reclamaciones ya no hace que el retorno IsAuthenticated sea verdadero. En su lugar, necesita pasar alguna cadena (no importa qué) al constructor.

Así que esta línea en el código anterior:

var claimsIdentity = new ClaimsIdentity( claims );

Se convierte en esto:

// exact string doesn't matter
var claimsIdentity = new ClaimsIdentity( claims, "CustomApiKeyAuth" );

Y el problema está resuelto. Actualización: ver otra respuesta de Leo. El valor exacto de AuthenticationType puede o no ser importante dependiendo de qué más tenga en su canalización de auth.

Actualización 2: como sugirió Robin van der Knaap en los comentarios, uno de los valores System.Security.Claims.AuthenticationTypes podría ser apropiado.

var claimsIdentity = new ClaimsIdentity( claims, AuthenticationTypes.Password );

// and elsewhere in your application...
if (User.Identity.AuthenticationType == AuthenticationTypes.Password) {
    // ...
}
 111
Author: explunit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-17 17:26:52

Si bien la respuesta proporcionada tiene cierta validez en ella, no es del todo correcta. No puedes asumir que simplemente agregar cualquier cadena funcionará mágicamente. Como se indica en uno de los comentarios, esta cadena debe coincidir con uno de los AuthenticationTypes enumeración que a su vez debe coincidir con la especificada en el middleware OWIN authentication/authorization....por ejemplo...

public void ConfigureOAuth(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);

            OAuthAuthorizationServerOptions serverOptions = new OAuthAuthorizationServerOptions()
            {
                AllowInsecureHttp = true,
                TokenEndpointPath = new Microsoft.Owin.PathString("/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                AuthenticationType = AuthenticationTypes.Password,
                AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
                Provider = new AppAuthServerProvider()
            };


            app.UseOAuthAuthorizationServer(serverOptions);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
                {
                    AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
                    AuthenticationType = AuthenticationTypes.Password
                });            
        }

Sin embargo, en el escenario anterior no importaría mucho. Pero, si está utilizando más niveles de autenticación / autorización las reclamaciones se asociarán a la que coincida con la misma AuthenticationType...otro ejemplo es cuando se utiliza la autenticación de cookies...

public void Configuration(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "ApplicationCookie",
                LoginPath = new PathString("/auth/login")
            });
        }

Donde AuthenticationType describe el nombre de la cookie, ya que su aplicación puede haber obtenido otras cookies de otros proveedores, es importante que establezca la AuthenticationType al instanciar las notificaciones para asociarlas a la cookie correcta

 10
Author: Leo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-25 02:10:25