Dlaczego moje ClaimsIdentity isauthenticated jest zawsze fałszywe (dla Web api Authorize filter)?
W projekcie Web API nadpisuję normalny proces uwierzytelniania, aby sprawdzić tokeny. Kod wygląda mniej więcej tak:
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;
}
I później, gdy zastosuję atrybut [Authorize]
do kontrolera, nie autoryzuje się.
Kod debugowania potwierdza to samo zachowanie:
// ALWAYS FALSE!
if ( HttpContext.Current.User.Identity.IsAuthenticated ) {
// do something
}
Dlaczego uważa, że użytkownik nie jest uwierzytelniony, mimo że skonstruowałem poprawne roszczenie i przypisałem je do wątku?
2 answers
Problem jest spowodowany przełomową zmianą w. Net 4.5. Jak wyjaśniono w w tym artykule , po prostu konstruowanie tożsamości twierdzenia nie sprawia już, że jest to prawdziwy zwrot IsAuthenticated. Zamiast tego musisz przekazać jakiś ciąg znaków (nie ma znaczenia co) do konstruktora.
Więc ta linijka w powyższym kodzie:
var claimsIdentity = new ClaimsIdentity( claims );
Staje się to:
// exact string doesn't matter
var claimsIdentity = new ClaimsIdentity( claims, "CustomApiKeyAuth" );
I problem został rozwiązany. Update: zobacz inne odpowiedzi od Leo. Dokładna wartość AuthenticationType może być ważne w zależności od tego, co jeszcze masz w potoku auth.
Aktualizacja 2: zgodnie z sugestią Robina van der Knaap w komentarzach, jedna z wartości System.Security.Claims.AuthenticationTypes
może być odpowiednia.
var claimsIdentity = new ClaimsIdentity( claims, AuthenticationTypes.Password );
// and elsewhere in your application...
if (User.Identity.AuthenticationType == AuthenticationTypes.Password) {
// ...
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-17 17:26:52
Chociaż udzielona odpowiedź ma w sobie pewną ważność, nie jest do końca poprawna. Nie można zakładać, że samo dodanie dowolnego ciągu będzie magicznie działać. Jak podano w jednym z komentarzy, ciąg ten musi pasować do jednego z AuthenticationTypes
wyliczenie, które z kolei musi być zgodne z podanym w OWIN authentication / authorization middleware....na przykład...
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
});
}
Jednak w powyższym scenariuszu nie miałoby to większego znaczenia. Ale jeśli używasz więcej poziomów uwierzytelniania/autoryzacji roszczenia będą powiązane z tym, który pasuje do tego samego AuthenticationType
...innym przykładem jest użycie uwierzytelniania plików cookie...
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "ApplicationCookie",
LoginPath = new PathString("/auth/login")
});
}
Gdzie AuthenticationType
opisuje nazwę pliku cookie, ponieważ Twoja aplikacja mogła uzyskać inne pliki cookie od innych dostawców, ważne jest, aby ustawić AuthenticationType
podczas tworzenia instancji roszczeń, aby powiązać je z prawidłowym plikiem cookie
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-25 02:10:25