为什么我的ClaimsIdentity总是被authentication为false(对于web api授权filter)?

在Web API项目中,我重写了正常的身份validation过程来检查令牌。 代码看起来像这样:

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; } 

然后,当我将[Authorize]属性应用于控制器时,将无法授权。

debugging代码确认相同的行为:

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

为什么它认为即使我已经构造了一个有效的ClaimsIdentity并将其分配给该线程,用户还没有被authentication?

问题是由于.Net 4.5中的一个突破性变化。 正如本文所解释的那样,简单地构造一个声明标识不再使它的IsAuthenticated返回true。 相反,你需要传递一些string(无所谓)到构造函数中。

所以这行代码如下:

 var claimsIdentity = new ClaimsIdentity( claims ); 

变成这样:

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

问题解决了。

我想这个问答大部分都是对链接文章的重述,但问题很难find,所以我希望通过增加这个,我会在未来让更多的Google能够为其他人服务。

虽然所提供的答案在其中有一些有效性,但并不完全正确。 你不能认为只是添加任何string将神奇地工作。 正如其中一个注释所述,该string必须匹配其中一个AuthenticationTypes枚举,该枚举又必须与OWINauthentication/授权中间件中指定的一个相匹配…例如…

 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 }); } 

但是,在上述情况下,这并不重要。 但是,如果您使用更多的身份validation/授权级别声明将关联到匹配相同的AuthenticationType …另一个例子是当您使用Cookie身份validation…

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

其中AuthenticationType描述了Cookie的名称,因为您的应用程序可能从其他提供商获得了其他Cookie,因此在实例化声明时设置AuthenticationType非常重要,然后才能与正确的Cookie关联