![](/img/trans.png)
[英].NET Web Api 2 UserPrincipal.IsAuthenticated always false when using dependency injection (Unity)
[英]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.