Mam wymaganie zabezpieczenia punktu końcowego usługi net.tcp usługi WCF za pomocą WIF . Powinien on uwierzytelniać połączenia przychodzące przeciwko naszemu serwerowi tokenów. Usługa jest przesyłana strumieniowo, ponieważ jest przeznaczona do przesyłania dużych ilości danych i innych rzeczy.
To wydaje się niemożliwe. A jeśli nie uda mi się obejść haczyka, moje Boże Narodzenie zostanie zrujnowane i wypiję się na śmierć w rynsztoku, podczas gdy wesoło kupujący przechodzą nad moim powoli ochładzającym się ciałem. Poważnie, chłopaki.
Dlaczego to jest niemożliwe? Oto Catch-22.
Na kliencie muszę utworzyć kanał z GenericXmlSecurityToken, który otrzymuję z naszego serwera tokenów. Bez problemu.
// people around here hate the Framework Design Guidelines.
var token = Authentication.Current._Token;
var service = base.ChannelFactory.CreateChannelWithIssuedToken(token);
return service.Derp();
Czy powiedziałem „bez problemu”? Problemo W rzeczywistości NullReferenceException
problem stylu.
„Bro”, zapytałem Framework, „czy w ogóle sprawdzasz zerowo?” Framework był cichy, więc zdemontowałem i znalazłem to
((IChannel)(object)tChannel).
GetProperty<ChannelParameterCollection>().
Add(federatedClientCredentialsParameter);
było źródłem wyjątku i że GetProperty
połączenie było zwracane null
. Więc WTF? Okazuje się, że jeśli włączę Zabezpieczenia wiadomości i ustawię typ poświadczenia klienta na, IssuedToken
wówczas ta właściwość istnieje teraz w ClientFactory
(protip: Nie ma odpowiednika „SetProperty” w IChannel, draniu).
<binding name="OMGWTFLOL22" transferMode="Streamed" >
<security mode="Message">
<message clientCredentialType="IssuedToken"/>
</security>
</binding>
Słodkie. Nigdy więcej NRE. Jednak teraz mój klient ma wadę od urodzenia (nadal go kocham, tho). Przekopując się przez diagnostykę WCF (protip: zmuś swoich najgorszych wrogów do zrobienia tego po zmiażdżeniu ich i poprowadzeniu ich przed tobą, ale tuż przed czerpaniem przyjemności z rozpaczy ich kobiet i dzieci), widzę, że jest to spowodowane niedopasowaniem bezpieczeństwa między serwerem a klientem.
Żądana aktualizacja nie jest obsługiwana przez „net.tcp: // localhost: 49627 / MyService”. Przyczyną może być niedopasowane powiązania (na przykład zabezpieczenia włączone na kliencie, a nie na serwerze).
Sprawdzając diagi gospodarza (ponownie: zmiażdż, jeźdź, czytaj dzienniki, ciesz się lamentami), widzę, że to prawda
Typ protokołu application / ssl-tls został wysłany do usługi, która nie obsługuje tego typu aktualizacji.
„Cóż, ja” - mówię - po prostu włączę ochronę wiadomości na hoście! I ja tak. Jeśli chcesz wiedzieć, jak to wygląda, jest to dokładna kopia konfiguracji klienta. Sprawdzać.
Wynik: Kaboom.
Powiązanie („NetTcpBinding”, „ http://tempuri.org/ ”) obsługuje przesyłanie strumieniowe, którego nie można skonfigurować razem z zabezpieczeniami na poziomie wiadomości. Zastanów się nad wyborem innego trybu przesyłania lub zabezpieczeniem na poziomie transportu.
Tak więc mój host nie może być przesyłany strumieniowo i zabezpieczany za pomocą tokenów . Złap 22.
tl; dr: Jak zabezpieczyć strumieniowany punkt końcowy WCF net.tcp za pomocą WIF ???
<security mode="Transport" /> <transport clientCredentialType="IssuedToken" /> </security>
TransportWithMessageCredential
tryb może być inną opcją.Odpowiedzi:
WCF ma problemy z transmisją strumieniową w kilku obszarach (patrzę na ciebie, MTOM 1 ) ze względu na podstawowy problem polegający na tym, że nie wykonuje wstępnego uwierzytelnienia w sposób, w jaki większość ludzi uważa, że powinno to działać (wpływa tylko na kolejne żądania dla tego kanału , nie pierwsza prośba) Ok, więc to nie jest dokładnie twój problem, ale proszę postępuj zgodnie z instrukcją, bo na końcu do ciebie dotrę. Zwykle wyzwanie HTTP działa w następujący sposób:
Teraz, jeśli kiedykolwiek spróbujesz włączyć strumieniowanie MTOM na punkcie końcowym WCF na serwerze, nie będzie narzekać. Ale jeśli skonfigurujesz go na serwerze proxy klienta (tak jak powinieneś, muszą one pasować do powiązań), wybuchnie to ognistą śmiercią. Powodem tego jest powyższa sekwencja zdarzeń, której WCF próbuje zapobiec:
Zauważ, że właśnie wysłałeś 200 MB na serwer, gdy wystarczyło tylko 100 MB. To jest problem. Odpowiedzią jest wysłanie uwierzytelnienia przy pierwszej próbie, ale nie jest to możliwe w WCF bez napisania niestandardowego zachowania. W każdym razie dygresję.
Twój problem
Po pierwsze, powiem ci, że to, czego próbujesz, jest niemożliwe 2 . Teraz, abyście przestali kręcić kołami, powiem wam, dlaczego:
Uderza mnie, że wędrujesz teraz w podobnej klasie problemów. Jeśli włączysz zabezpieczenia na poziomie komunikatu, klient musi załadować cały strumień danych do pamięci, zanim będzie mógł faktycznie zamknąć komunikat przy użyciu zwykłej funkcji skrótu i podpisu XML wymaganego przez ws-security. Jeśli musi odczytać cały strumień, aby podpisać pojedynczą wiadomość (która tak naprawdę nie jest wiadomością, ale jest to pojedynczy ciągły strumień), możesz zobaczyć problem tutaj. WCF będzie musiał przesłać go raz „lokalnie”, aby obliczyć bezpieczeństwo wiadomości, a następnie przesłać ją ponownie, aby wysłać ją na serwer. Jest to oczywiście głupia sprawa, więc WCF nie zezwala na bezpieczeństwo na poziomie komunikatów dla przesyłania strumieniowego danych.
Tak więc prosta odpowiedź tutaj jest taka, że powinieneś wysłać token albo jako parametr do początkowej usługi internetowej, albo jako nagłówek SOAP i użyć niestandardowego zachowania, aby to sprawdzić. W tym celu nie można użyć WS-Security. Szczerze mówiąc, nie jest to tylko kwestia WCF - nie widzę, jak mogłaby praktycznie działać dla innych stosów.
Rozwiązywanie problemu MTOM
To tylko przykład, w jaki sposób rozwiązałem problem z transmisją MTOM dla podstawowego uwierzytelnienia, więc być może mógłbyś spróbować i wdrożyć coś podobnego do swojego problemu. Chodzi o to, że aby włączyć niestandardowego inspektora wiadomości, musisz wyłączyć wszelkie pojęcia bezpieczeństwa na klienckim serwerze proxy (pozostaje ono włączone na serwerze) oprócz poziomu transportu (SSL):
Pamiętaj, że wyłączyłem tutaj zabezpieczenia transportu, ponieważ zapewniam, że korzystam z inspektora wiadomości i niestandardowego zachowania:
Tak więc, ten przykład jest dla każdego, kto cierpi na problem MTOM, ale także jako szkielet do zaimplementowania czegoś podobnego do uwierzytelnienia tokena wygenerowanego przez podstawową usługę tokenu zabezpieczoną przez WIF.
Mam nadzieję że to pomoże.
(1) Duże dane i przesyłanie strumieniowe
(2) Bezpieczeństwo wiadomości w WCF (patrz „wady”)
źródło
MTOM and Basic Authorization
oraz MTOM i OAuth2 ?