En una Web API proyecto en el que estoy anulando el normal proceso de autenticación para comprobar fichas 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, a continuación, más tarde, cuando yo aplique el [Authorize] atributo a un controlador, no autorizar.

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

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

¿Por qué se considera que el usuario no está autenticado, aunque he construido una válida ClaimsIdentity y se ha asignado a la rosca?

InformationsquelleAutor explunit | 2013-11-27

2 Comentarios

  1. 121

    El problema es debido a un cambio de hora en .Net 4.5. Según lo explicado por este artículo, simplemente la construcción de una reclamos de la identidad ya no hace IsAuthenticated devolver true. En su lugar, usted necesita para pasar una cadena (no importa qué) en el constructor.

    Por lo 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. La exacta AuthenticationType valor puede o no ser importante, dependiendo de lo demás que usted tiene en su auth tubería.

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

    var claimsIdentity = new ClaimsIdentity( claims, AuthenticationTypes.Password );
    
    //and elsewhere in your application...
    if (User.Identity.AuthenticationType == AuthenticationTypes.Password) {
        //...
    }
    • Aunque se podría añadir cualquier cadena de caracteres, de acuerdo a MSDN normalmente, esto debe ser uno de los valores definidos en la AuthenticationTypes clase. msdn.microsoft.com/en-us/library/…
    • Ejemplo: var claimsIdentity = new ClaimsIdentity( reclamos, AuthenticationTypes.La contraseña );
    • El valor de la cadena se hace visible en el Usuario.De la identidad.AuthenticationType
    • Wow eso es muy oscuro! Gracias por compartir esta aquí! Me quedé más de una hora.
    • Gracias, gracias, muchas gracias!
  2. 11

    Mientras que la respuesta tiene cierta validez en ella, lo que no es del todo correcto. No se puede asumir que sólo la adición de cualquier cadena por arte de magia el trabajo. Como se indica en uno de los comentarios, esta cadena debe coincidir con uno de los AuthenticationTypes la enumeración que a su vez debe coincidir con el especificado en el OWIN de autenticación/autorización de middleware….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 usted está usando más de autenticación/autorización de los niveles de las reclamaciones serán asociados para el que coincida con el mismo AuthenticationType…otro ejemplo es cuando el uso de la cookie de autenticación…

    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 tener obtenido otras cookies de otros proveedores es importante que establezca la AuthenticationType al crear instancias de las reclamaciones con el fin de asociar a continuación, para la correcta cookie

    • En .NET Core puede utilizar constantes como AuthenticationType, por ejemplo, CookieAuthenticationDefaults.AuthenticationScheme o JwtBearerDefaults.AuthenticationScheme.
    • Nota, a la hora de crear ClaimsIdentity, debe pasar el nombre de esquema como el AuthenticationType (como new ClaimsIdentity(claims, AuthenticationScheme)). De lo contrario, la IsAuthenticated bandera de la identidad va a ser false. Me metí en el mismo no intuitivo problema dos veces en los últimos 2 años, y esta respuesta me ayudó de nuevo. No puede upvote esta respuesta dos veces por desgracia.

Dejar respuesta

Please enter your comment!
Please enter your name here