簡體   English   中英

為什么我的ClaimsIdentity IsAuthenticated始終為false(對於web api授權過濾器)?

[英]Why is my ClaimsIdentity IsAuthenticated always false (for web api Authorize filter)?

在Web API項目中,我重寫了正常的身份驗證過程來檢查令牌。 代碼看起來像這樣:

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]屬性應用於控制器時,它無法授權。

調試代碼確認相同的行為:

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

為什么即使我構建了有效的ClaimsIdentity並將其分配給線程,它也認為用戶未經過身份驗證?

問題是由於.Net 4.5的突破性變化。 正如本文所解釋的那樣,簡單地構建聲明標識不再使其IsAuthenticated返回true。 相反,您需要將一些字符串(無關緊要)傳遞給構造函數。

所以在上面的代碼中這一行:

var claimsIdentity = new ClaimsIdentity( claims );

變成這樣:

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

問題解決了。 更新:請參閱Leo的其他答案。 確切的AuthenticationType值可能重要,也可能不重要,具體取決於您在auth管道中的其他內容。

更新2:正如Robin van der Knaap在評論中所建議的那樣, System.Security.Claims.AuthenticationTypes值之一可能是合適的。

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

// and elsewhere in your application...
if (User.Identity.AuthenticationType == AuthenticationTypes.Password) {
    // ...
}

雖然提供的答案在其中有一定的有效性,但它並不完全正確。 你不能假設只是添加任何字符串將神奇地工作。 正如其中一條評論所述,此字符串必須與AuthenticationTypes枚舉中的一個匹配,而該類型必須與OWIN認證/授權中間件中指定的枚舉匹配....例如......

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

但是,在上述情況下,這並不重要。 但是,如果您使用更多身份驗證/授權級別,聲明將與匹配相同AuthenticationType的聲明關聯...另一個示例是您使用Cookie身份驗證時...

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

其中AuthenticationType描述了cookie的名稱,因為您的應用程序可能已從其他提供程序獲取其他cookie,因此在實例化聲明時設置AuthenticationType以便將其關聯到正確的cookie非常重要

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM