Sesje WCF z wshttpbindingiem i bez zabezpieczeń windows

Muszę utworzyć usługę WCF, która jest hostowana w IIS, używa transportu http i utrzymuje stan w pamięci serwera. Chociaż zdaję sobie sprawę, że stateful services nie są dobrym pomysłem, ta ostatnia ograniczenie jest konieczne, aby usługa działała ze starszym klientem.

Moją pierwszą myślą było asp.net sesji do przechowywania wartości. Aktywowałem asp.net tryb zgodności w moim serwisie, który dał mi dostęp do HttpContext, ale wartości, które zostały umieszczone w obiekcie sesji nie były / align = "left" / Zakładam, że było tak dlatego, że moduł http obsługujący stan sesji nie był poprawnie skonfigurowany, ale podczas googlowania po odpowiedź natknąłem się na sesje WCF i pomyślałem, że może być lepszym pomysłem, aby z nich korzystać.

Jednak sesje WCF wydają się co pod-dokument i umieścić dziwny zestaw warunków wstępnych w usłudze, a ja nie byłem w stanie znaleźć konfiguracji, która odpowiada moim potrzebom: musi być hostowany w IIS, musi używać transportu http lub https i nie mogę odpowiedzieć na windows uwierzytelnianie, ponieważ klient i serwer nie będą częścią tej samej domeny. Próbuję to zrobić używając wsHttpBinding, słyszałem, że sesje WCF wymagają albo bezpieczeństwa, albo niezawodnej wiadomości, ale: - Korzystanie ze standardowego wiązania i gdy serwery nie są częścią tej samej domeny, zawodzi z wyjątkiem" SecurityNegotiationException the caller was not authenticated by the service". Jest to dość logiczne, ponieważ używało zabezpieczeń systemu windows.

  • Jeśli wyłączę security complete it fails with a "Contract requires Session, but Binding 'WSHttpBinding' doesn ' t support it or is not configured properly to support it."

  • Jeśli podczas utrzymywania bezpieczeństwa wyłączony włącz niezawodny komunikat dostaję wyjątek " Walidacja wiązania nie powiodła się, ponieważ WSHttpBinding nie obsługuje niezawodnych sesji nad bezpieczeństwem transportu (HTTPS). Nie można otworzyć fabryki kanału lub hosta usług. Użyj message security, aby zabezpieczyć niezawodne przesyłanie wiadomości przez HTTP."

  • Próbowałem włączyć zabezpieczenia na poziomie transportu, ale wydaje się, że nie ma to żadnej różnicy w wygenerowanym błędzie

Czy jest jakaś konfiguracja, która może mi się udać? A może po prostu wrócić do planu użycia asp.net sesje?

Author: abatishchev, 2011-01-22

2 answers

Możesz mieć WCF trzymać informacje o sesji w pamięci w dość prosty sposób. Aby wyeliminować wszelkie możliwe wpływy zewnętrzne w moich instrukcjach, zakładam, że zaczynasz od zupełnie nowego projektu: {]}

  1. Utwórz nowy projekt biblioteki usług WCF. Ten projekt będzie już zawierał usługę z wstępnie skonfigurowanym wiązaniem WSHttpBiding.
  2. Przejdź do umowy serwisowej (IService1.cs) I zmienić atrybut ServiceContract na następujący:

    [ServiceContract(SessionMode = SessionMode.Required)]
    
  3. Przejdź do implementacji usługi (Service1.cs) i dodać następujący atrybut ServiceBehavior do klasy service (Service1):

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
    
  4. Dodaj dane sesji jako członków klasy usług (Service1):

    public class Service1 : IService1
    {
        ...
    
        private string UserFullName { get; set; }
    
        ...
    }
    
  5. Użyj członków do przedstawienia konkretnych danych sesji (pamiętaj, aby dodać je również do umowy o świadczenie usług, IService1):

    public class Service1 : IService1
    {
        ...
    
        public string Welcome(string fullName)
        {
            UserFullName = fullName ?? "Guest";
            return string.Format("Welcome back, {0}!", UserFullName);
        }
    
        public string Goodbye()
        {
            return string.Format("Come back soon, {0}!", UserFullName ?? "Guest");
        }
    
        ...
    }
    

SessionMode.Required zapewnia, że twoi klienci są Śledzenie sesji.
InstanceContextMode.PerSession zapewnia utworzenie instancji klasy usługi (Service1) dla każdej sesji, dzięki czemu można zachować w niej dane sesji i będą one istniały w pamięci podczas wielu wywołań w tej samej sesji.
ConcurrencyMode.Single zapewnia, że tylko jeden wątek może wejść do każdej instancji klasy usługi (Service1) i zapobiega możliwym problemom z współbieżnością, jeśli masz dostęp tylko do danych z klasy usługi (i zewnętrznego wątku-safe miejsca).

EDIT: domyślnie, WSHttpBinding zezwala tylko na sesje bezpieczeństwa. Ale obsługuje również niezawodne sesje, które umożliwiają tworzenie sesji bez włączonych zabezpieczeń. Następująca konfiguracja wiązań wyłącza zabezpieczenia i włącza niezawodne sesje:

<wsHttpBinding>
    <binding name="wsHttpBindingConfiguration">
        <security mode="None" />
        <reliableSession enabled="true" />
    </binding>
</wsHttpBinding>
 25
Author: Allon Guralnek,
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
2011-01-22 20:28:13

IMO tak się dzieje, gdy używasz technologii ze słabą abstrakcją na HTTP, takiej jak WCF. Fakt, że WCF Web services może teoretycznie być hostowane bez HTTP (tj. przez NET TCP, MSMQ, itp.) Po prostu sprawia, że trudno jest używać wbudowanych funkcji HTTP bez wchodzenia w piekło konfiguracji i rozpocząć grę "Odgadnij poprawną konfigurację metodą prób i błędów", w której próbujesz każdej możliwej permutacji konfiguracji, dopóki nie znajdziesz poprawnej, która działa!

Ostatecznie jeśli nie mogłeś użyć WCF i musiałeś zaimplementować usługę internetową od zera, po prostu Ustawiłeś plik cookie, gdy klient pomyślnie uwierzytelnił się. Następnie z każdym żądaniem klienta po prostu pobierz informacje o sesji, do których odnosi się ten plik cookie.

Jednym z możliwych rozwiązań, jeśli musisz użyć WCF, jest przejęcie zarządzania sesją we własne ręce (to właśnie robię, gdy nie jestem zadowolony z wysiłku wymaganego, aby coś zadziałało) i posiadanie wyraźnej właściwości "sesji" na wszystkich Twoich stronach internetowych usługi wymagające sesji / uwierzytelniania (Zwykle guid generowany podczas uwierzytelniania). Tak więc dla każdego kolejnego żądania używasz identyfikatora guid do ponownego nawodnienia informacji o sesji związanych z tym klientem.

Jeśli jesteś zainteresowany wypróbowaniem różnych frameworków usług internetowych, utrzymuję open Source Web Services Framework, który pozwala Ci budować wolne od konfiguracji, suche, testowalne Usługi internetowe, gdzie (bez żadnej konfiguracji wymaganej) każda tworzona usługa internetowa jest automatycznie dostępne przez punkty końcowe REST XML, JSON, JSV, SOAP 1.1, SOAP 1.2. Skutecznie pozwala na dostęp do tej samej usługi internetowej za pośrednictwem adresu URL HTTP GET dla klientów REST-ful i łatwego debugowania, a także punktów końcowych SOAP (popularny wybór nadal wymagany przez niektóre przedsiębiorstwa). Tutorial Hello World powinien dać ci dobry przegląd niektórych jego funkcji i sposobu działania.

 1
Author: mythz,
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
2011-01-22 12:02:15