2012-03-20 15 views
11

Mam stronę, która jest stroną bazującą na niestandardowym STS opartym na WIF. Niedawno zaimplementowaliśmy pamięć podręczną tokenów bezpieczeństwa opisaną tutaj: Azure/web-farm ready SecurityTokenCache. Główna różnica między naszą implementacją a wersją opisaną w tym linku polega na tym, że zamiast przechowywania tabel korzystamy z buforowania aplikacji Azure AppFabric jako magazynu danych trwałej pamięci podręcznej. Pomogło nam to w rozwiązaniu problemu z obcinaniem tokena w niektórych przeglądarkach, ale wprowadziło nowy problem (Problem z obcinaniem pojawia się głównie na stronach, które oprócz plików cookie goangel analytics + antiiforgery oprócz pliku cookie fedauth). Jesteśmy teraz otrzymania następującym wyjątkiem kilka tysięcy razy dziennie:Buforowanie tokenów zabezpieczających WIF

System.IdentityModel.Tokens.SecurityTokenException 
ID4243: Could not create a SecurityToken. A token was not found in the token cache and no cookie was found in the context. 

System.IdentityModel.Tokens.SecurityTokenException: ID4243: Could not create a  SecurityToken. A token was not found in the token cache and no cookie was found in the context. 
    at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver) 
    at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver) 
    at Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie) 
    at Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken) 
    at Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs) 
    at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

Wyjątek ten wydaje się dzieje w pętli przekierowanie, więc zobaczymy ich setki w przedziale czasowym 1-2 minut.

Nie mogę znaleźć żadnych użytecznych informacji podczas badania wyjątku. Jedynym samorodkiem, który ma jak dotąd nadzieję, jest ktoś, kto wspomniał, że może być powiązany z wygaszonym obiektem wygasającym przed sesją.

Nie byliśmy w stanie odtworzyć problemu wewnętrznie i wiemy tylko, że istnieje z powodu tysięcy wpisów wypełniających nasze tabele Elmah. Każda pomoc lub wgląd byłyby bardzo doceniane.

Mamy wypchnięty co myśleliśmy może pomóc rozwiązać ten problem (kod poniżej), ale to nie miało żadnego wpływu:

HttpContext.Current.Response.Cookies.Remove("FedAuth"); 
WSFederationAuthenticationModule authModule = FederatedAuthentication.WSFederationAuthenticationModule; 
string signoutUrl = (WSFederationAuthenticationModule.GetFederationPassiveSignOutUrl(authModule.Issuer, authModule.Realm, null)); 
Response.Redirect(signoutUrl); 

Odpowiedz

0

należy to zrobić, jeśli liczba roszczeń token lub całkowitej wielkości z token jest zbyt duży, aby można go było przenosić w ciasteczkach. Jeśli tak nie jest, uprość rozwiązanie i po prostu użyj domyślnego ustawienia, które używa plików cookie. Jednak używasz szyfrowania plików cookie na podstawie certyfikatu, więc nadal jest "przyjazny dla farmy". Domyślnie WIF będzie enrcrypt używać DPAPI, który ma powinowactwo maszyny.

+1

Wdrożyliśmy token cache ponieważ nasz wspólny stos ciasteczek było przekroczenie limitu rozmiaru domeny cookies 4096 bajtów w niektórych przeglądarek (Safari, Opera, itp). Został zaimplementowany w odpowiedzi na problem z obcinaniem plików cookie. Korzystamy również z szyfrowania plików cookie na podstawie certyfikatu. Pamięć podręczna tokenów bezpieczeństwa jest dla nas "koniecznością" i ma taki efekt, na jaki liczyliśmy, ale implementacja stworzyła ten nowy wyjątek. Prawdziwy problem z tym wyjątkiem polega na tym, że rzuca on naszych użytkowników w pętlę przekierowania. – Jeff

1

Widzimy dokładnie ten błąd, jeśli przejdziemy do świeżo uruchomionej aplikacji, podczas gdy przeglądarka nadal przechowuje plik cookie z wcześniejszej sesji. Ponieważ te pliki cookie są plikami cookie sesji, poprawka polega na zamknięciu wszystkich okien przeglądarki i ponownym przejściu do aplikacji.

Nasza aplikacja to "normalna" aplikacja internetowa przekierowująca do AD FS za pomocą WIF bez żadnych specjalnych elementów pamięci podręcznej tokenów bezpieczeństwa, o ile wiem. Jednakże używamy "trybu sesji" w przypadku plików WIF (patrz np. "Your FedAuth Cookies on a Diet: IsSessionMode=true"), dzięki czemu pliki WIF są znacznie mniejsze.

+0

Jak moglibyśmy to zmienić, aby mieć pewność, że to jest problem i jak możemy temu zapobiec? Sprawdzę, ale wydaje mi się, że pozwalamy przeglądarce na 24 godziny, a następnie odświeżamy, aby sprawdzić, czy uda nam się ją zaimportować, a nie. Czy musimy upewnić się, że był również start/restart aplikacji? Nie jestem w 100% pewny, co masz na myśli, mówiąc "świeżo rozpoczęta aplikacja". –

1

Obecnie mamy dokładnie ten sam problem, chociaż nasza sytuacja jest nieco inna. Próbujemy korzystać z WIF, aby zapewnić SSO Shibboleth dla aplikacji internetowej Outlook (OWA). Mamy kilka hostów OWA za równoważnikiem obciążenia.

WIF generuje plik cookie FedAuth (i FedAuth1) o rozmiarze większym niż 2,5 kB. Nasz moduł równoważący obciążenia obcina plik cookie. Dlatego ustawiamy IsSessionMode -Property na true w pliku global.aax OWA. Teraz rozmiar pliku cookie jest zmniejszony do około. 600 bajtów, co jest w porządku. Działa OWA.

Jednak Exchange Control Panel (ECP) działający na tym samym serwerze nie działa. ECP działa w tej samej puli aplikacji IIS i ma również zestaw IsSessiobnMode-Property w pliku global.asax. Ilekroć ECP nazywa, aplikacja nie wysyła z powrotem żadnej odpowiedzi, ale WIF donosi:

Current user: 'User not set' 
    Request for URL 'http://owa.ourdomain.com/ecp/' failed with the following error: 
    System.IdentityModel.Tokens.SecurityTokenException: ID4243: Could not create a SecurityToken. A token was not found in the token cache and no cookie was found in the context. 
2

ten problem spowodowany przez buforowanie SessionSecurityToken.Miejsce docelowe pamięci podręcznej znajduje się w lokalnej domenie puli aplikacji, więc gdy .NET potrzebuje pamięci, zostanie ona automatycznie usunięta. Najlepszym rozwiązaniem jest anulowanie buforowania dla bezpieczeństwa lub wdrożenie własnego podsystemu do buforowania.

rozwiązanie 1

AppFabric Windows Server memcached - System rozproszony obiekt buforowania pamięci

Rozwiązanie 2

var sessionSecurityToken = new SessionSecurityToken(principal, TimeSpan.FromHours(Convert.ToInt32(System.Web.Configuration.WebConfigurationManager.AppSettings["SessionSecurityTokenLifeTime"]))) 
{ 
    IsPersistent = false, // Make persistent 
    IsReferenceMode = true // Cache on server 
}; 
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken); 
5

Mam aplikacji strona pojedynczy MVC jako strona ufająca wykorzystaniem WSO2 4,5 jako IDP i otrzymywał ten sam błąd - "System.IdentityModel.Tokens.SecurityTokenException ID4243: Nie można utworzyć elementu SecurityToken. Token nie został znaleziony w pamięci podręcznej tokenów, a nie plik cookie został znaleziony w kontekście. ... "Przeszukano i znalazłem poniższe stwierdzenia Brock Allen o sławie Thinktecture

Ten wyjątek jest zgłaszany, gdy przeglądarka wysyła plik cookie zawierający oświadczenia użytkownika, ale nie można uzyskać informacji o przetwarzaniu. wykonywany (klucz został zmieniony, więc token nie może zostać sprawdzony, lub jeśli używana jest pamięć podręczna po stronie serwera, a pamięć podręczna jest pusta) .Koniec nie będzie w stanie wiele z tym zrobić i zamierzają . nadal pojawia się błąd, ponieważ przeglądarka będzie nadal wysyłać cookie

Pełny artykuł: http://brockallen.com/2012/10/22/dealing-with-session-token-exceptions-with-wif-in-asp-net/

W tym samym artykule podaje poniższy fragment kodu, który rozwiązał problem w moim przypadku. W Global.asax:

void Application_OnError() 
{ 
    var ex = Context.Error; 
    if (ex is SecurityTokenException) 
    { 
     Context.ClearError(); 
     if (FederatedAuthentication.SessionAuthenticationModule != null) 
     { 
      FederatedAuthentication.SessionAuthenticationModule.SignOut(); 
     } 
     Response.Redirect("~/"); 
    } 
}