Why is my ClaimsIdentity IsAuthenticated always false (for web api Authorize filter)?
在一个Web API项目中,我替代了常规的身份验证过程来检查令牌。 代码看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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; } |
然后,当我将
调试代码确认相同的行为:
1 2 3 4 | // ALWAYS FALSE! if ( HttpContext.Current.User.Identity.IsAuthenticated ) { // do something } |
为什么即使我已经构建了有效的ClaimsIdentity并将其分配给线程,用户仍未通过身份验证?
问题是由于.Net 4.5中的重大更改。如本文所述,仅构造声明身份不再使IsAuthenticated返回true。相反,您需要将一些字符串(无关紧要)传递给构造函数。
因此以上代码中的这一行:
1 |
变成这个:
1 2 | // exact string doesn't matter var claimsIdentity = new ClaimsIdentity( claims,"CustomApiKeyAuth" ); |
问题就解决了。更新:请参阅Leo的其他答案。确切的AuthenticationType值可能重要,也可能不重要,具体取决于您在身份验证管道中还有哪些内容。
更新2:如Robin van der Knaap在评论中所建议,
1 2 3 4 5 6 | var claimsIdentity = new ClaimsIdentity( claims, AuthenticationTypes.Password ); // and elsewhere in your application... if (User.Identity.AuthenticationType == AuthenticationTypes.Password) { // ... } |
尽管所提供的答案具有一定的有效性,但并不完全正确。您不能假设仅添加任何字符串都能神奇地工作。如注释之一所述,该字符串必须与
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 }); } |
但是,在上述情况下,这没什么大不了的。但是,如果您使用更多身份验证/授权级别,则声明将与匹配相同
1 2 3 4 5 6 7 8 |
其中