Haarig! WCF Router mit Zertifikaten und MessageInspektor

19/05/2010 - 16:01 von jens d | Report spam
Hallo,

ich habe einen WCF Client und Service, welche per Nachrichten- oder
Transportsicherheit jeweils mit Zertifikaten verschlüsselt kommunizieren.

Jeder Nachricht wird mit einem Behavior ein zusàtzlicher Header
hinzugefügt, in dem z.B. Sitzungsdaten enthalten sind.

Jetzt möchte ich einen Router bauen (siehe hier:
http://bebugsblog.blogspot.com/2010...rvice.html)
der aufgrund der Sitzungsdaten im Header ein Routing vornehmen kann und
gleichzeitig bei Ausfall eines Dienstes einen anderen anbieten kann.
(Falls es hier Links gibt, die mir Hinweise zum auslesen meines Headers
für das korrekte Routing bieten - bitte mit angeben! Danke!)

Ich habe inzw. nach dem obigen Beispiel einen Router implementiert, habe
aber nun das Problem, dass der Router scheinbar nicht mit dem Dienst
kommunizieren kann. Anfragen vom Client kommen aber an - dies kann ich
durch eine Konsolenausgabe bei der ReceiveRequest-Methode des Routers
und auch bei BeforeSendRequest sehen. Es kommt aber nichts beim Service an.

Ich habe keine Idee, woran es noch liegen könnte da ich die
Einstellungen für die direkte Kommunikation zwischen Client und Service
kopiert habe und auch keinen logischen Fehler finde..


BITTE HELFEN!

Fehlermeldung: {"The server did not provide a meaningful reply; this
might be caused by a contract mismatch, a premature session shutdown or
an internal server error."}

Hier die App.Config des Routers:


<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="SecNetTcpBinding">
<security mode="Message">
<transport clientCredentialType="Certificate" />
<message clientCredentialType="Certificate" />
</security>
</binding>
</netTcpBinding>
</bindings>

<extensions>
<behaviorExtensions>
<add name="Injection"
type="Company.ServiceModel.ServerMessageInspector, Company.ServiceModel,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<services>
<service behaviorConfiguration="CertRoutingData"
name="System.ServiceModel.Routing.RoutingService">
<endpoint behaviorConfiguration="InjectionBehavior"
binding="netTcpBinding"
bindingConfiguration="SecNetTcpBinding" name="reqReplyEndpoint"
contract="System.ServiceModel.Routing.IRequestReplyRouter">
<identity>
<dns value="WcfServer" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding"
name="reqReplyEndpointMetadata"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add
baseAddress="net.tcp://appserver:9999/Company/Application" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="CertInjectionBehavior">
<Injection />
<clientCredentials>
<clientCertificate findValue="WcfClient"
storeName="TrustedPeople"
x509FindType="FindBySubjectName" />
<serviceCertificate>
<defaultCertificate findValue="WcfServer"
x509FindType="FindBySubjectName" />
<authentication certificateValidationMode="PeerTrust" />
</serviceCertificate>
</clientCredentials>
</behavior>
<behavior name="InjectionBehavior">
<Injection />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="CertRoutingData">
<routing routeOnHeadersOnly="true"
filterTableName="FilterTable1" />
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust" />
</clientCertificate>
<serviceCertificate findValue="WcfServer"
storeLocation="CurrentUser"
x509FindType="FindBySubjectName" />
<peer>
<messageSenderAuthentication
certificateValidationMode="PeerTrust" />
</peer>
<issuedTokenAuthentication
certificateValidationMode="PeerTrust" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<client>
<endpoint
address="net.tcp://appserver:8888/Company/Application/UserService"
behaviorConfiguration="CertInjectionBehavior"
binding="netTcpBinding"
bindingConfiguration="SecNetTcpBinding" contract="*"
name="OutputEndpoint">
<identity>
<dns value="WcfServer" />
</identity>
</endpoint>
</client>
<routing>
<filters>
<filter name="MyFilter" filterType="MatchAll" />
</filters>
<filterTables>
<filterTable name="FilterTable1">
<add filterName="MyFilter" endpointName="OutputEndpoint" />
</filterTable>
</filterTables>
</routing>
</system.serviceModel>

und hier gekürzt die des Services:

<system.serviceModel>

<services>
<service behaviorConfiguration="serviceBehavior"
name="Application.Services.System.SessionService">
<endpoint address="System\SessionService"
behaviorConfiguration="InjectionBehavior"
binding="netTcpBinding" bindingConfiguration="netTcpBinding"
name="NetTcpSessionService"
contract="Application.Services.Contracts.System.ISessionServiceContract"
listenUriMode="Explicit">
<identity>
<dns value="WcfServer" />
</identity>
</endpoint>
<endpoint address="System/SessionService/Metadata"
binding="mexTcpBinding"
bindingConfiguration="" name="NetTcpSessionServiceMetadata"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add
baseAddress="net.tcp://AppServer:8888/Company/Application" />
<add
baseAddress="http://AppServer:8080//Company/Application/SessionService" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="serviceBehavior"
name="Application.Services.MasterData.UserService">
<endpoint address="MasterData/UserService"
behaviorConfiguration="InjectionBehavior"
binding="netTcpBinding" bindingConfiguration="netTcpBinding"
name="NetTcpUserService"
contract="Application.Services.Contracts.MasterData.IUserServiceContract"
listenUriMode="Explicit">
<identity>
<dns value="WcfServer" />
</identity>
</endpoint>
<endpoint address="MasterData/UserService/Metadata"
binding="mexTcpBinding"
bindingConfiguration="" name="NetTcpUserServiceMetadata"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add
baseAddress="net.tcp://AppServer:8888/Company/Application" />
<add
baseAddress="http://AppServer:8080//Company/Application/UserService" />
</baseAddresses>
</host>
</service>
</services>

<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust"/>
</clientCertificate>
<serviceCertificate findValue="WcfServer"
storeLocation="CurrentUser" x509FindType="FindBySubjectName"/>
<peer>
<messageSenderAuthentication
certificateValidationMode="PeerTrust"/>
</peer>
<issuedTokenAuthentication
certificateValidationMode="PeerTrust"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="InjectionBehavior">
<Injection/>
</behavior>
</endpointBehaviors>
</behaviors>

<bindings>
<netTcpBinding>
<binding name="netTcpBinding" receiveTimeout="00:05:00">
<reliableSession inactivityTimeout="00:05:00" />
<security mode="Message">
<transport clientCredentialType="Certificate" />
<message clientCredentialType="Certificate" />
</security>
</binding>
</netTcpBinding>
</bindings>

<extensions>
<behaviorExtensions>
<add name="Injection"
type="Company.ServiceModel.ServerMessageInspector, Company.ServiceModel,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>

</system.serviceModel>

Für jede Hilfe dankbar:
Jens
 

Lesen sie die antworten

#1 Frank Dzaebel
19/05/2010 - 21:10 | Warnen spam
Hallo Jens,

ich habe einen WCF Client und Service, welche per Nachrichten- oder
Transportsicherheit jeweils mit Zertifikaten verschlüsselt
kommunizieren.



Naja, da gibt es natürlich einiges, aber da Du sagst.
" [...]ein Routing vornehmen kann und gleichzeitig bei Ausfall
eines Dienstes einen anderen anbieten kann."
sehe ich ja eigentlich eher eine <backupList> für Dich als angebracht,
die ich allerdings nicht in Deiner Konfiguration sehe.

[Videos]

[[What's new in WCF4] Routing Service - or: Look ma: Just one service to
talk to! - Christian Weyer's Blog]
http://weblogs.thinktecture.com/cwe...lk-to.html

[10-4 Episode 40: The New WCF Routing Service | 10-4 | Channel 9]
http://channel9.msdn.com/shows/10-4...g-Service/

[TechDays 2010 : What's new in WCF 4 | liese | Channel 9]
http://channel9.msdn.com/posts/lies...-in-WCF-4/

[endpoint.tv - New in WCF 4 - System.ServiceModel.Routing | endpoint.tv |
Channel 9]
http://channel9.msdn.com/shows/Endp...elRouting/

MSDN:

Alles unterhalb von:

[Routing]
http://msdn.microsoft.com/de-de/lib...17421.aspx

[Routingdienst]
http://msdn.microsoft.com/de-de/lib...17418.aspx

[<backupLists>]
http://msdn.microsoft.com/de-de/lib...16883.aspx

[Vorgehensweise: Fehlerbehandlung]
http://msdn.microsoft.com/de-de/lib...16886.aspx



[...] (Falls es hier Links gibt, die mir Hinweise zum auslesen meines
Headers für das korrekte Routing bieten - bitte mit angeben! Danke!)



Fiddler eignet sich da im Prinzip ganz gut.
Aber die Header sind doch aus den Unter-Eigenschaften
(zum Beispiel) des WCF-CLient-Proxies auslesbar ... etwa:
"requestMessage.Headers"

[Service Station: Erstellen eines WCF-Routers, Teil 2]
http://msdn.microsoft.com/de-de/mag...#id0210053

Ansonsten sind Fragen dieses Themas natürlich
besser in spezialisierten Foren wie:

[Windows Communication Foundation Forum]
http://social.msdn.microsoft.com/Fo...cf/threads

[Windows Communication Foundation (WCF) Forum]
http://social.msdn.microsoft.com/Fo...de/threads

aufgehoben.




Es kommt aber nichts beim Service an.



ok, auch, wenn ich Deine WCF-Konfiguration jetzt nicht
100% (aus Zeitgründen) nachvollziehen kann, will ich Dir
ein paar Tips geben (und manches, was mir auffiel) , die man
auch recht allgemein in anderen WCF-Szenarien gelten, aber
für Dich hier dennoch zielführend sein können.

**Zertifikate**
Wenn Du mit Zertifikaten arbeitest müssen die auf dem
Server auch installiert sein. Installieren tust Du die im
Entwickler-Szenario mit einem makecert-Befehl.
Unbedingt darauf achten, dass diese in "Trusted People"
(Vertrauenswürdige Personen) landen ... manche Batch-
Beispiele aus der Doku oder in codeproject-Artikeln tun das
nicht richtig. Richtig sehen tust Du das Zertifikat normal am
besten über die MMC (... Zertifikate-Snap-In hinzufügen).



**PeerTrust**
Vielleicht mal zunàchst mit [certificateValidationMode="None"] versuchen.
(das soll nicht heißen, das es nicht funktioniert)

[WCF PeerTrust certificate configuration is not working properly]
http://social.msdn.microsoft.com/Fo...e6b2529d4c

[Verwenden von Zertifikaten]
http://msdn.microsoft.com/de-de/lib...31899.aspx



**Erhöhte Rechte**
Gerade der WCF-Service selber benötigt für das Abbonieren
des Listeners erhöhte Rechte. Im ersten Anlauf vielleicht
mal (z.B. bei Hosting über Windows Dienst) mit LocalSystem
probieren.




might be caused by a contract mismatch, a premature session shutdown or
an internal server error."}



Ganz wichtig auch das :

**Close - Neuerstellen - Prinzip**
- Erstelle vor dem Aufruf einer WCF-Client-Methode den
WCF-Client-Proxy-Klasse neu.
Rufe die WCF-Client-Methoden dann ganz normal (ggf. mit
ihren asynchronen Varianten auf, aber bette sie in ein try-catch ein,
dass dann innerhalb des Catch ein Abort/ bzw. Close, wenn es geklappt
hat,
ausführt.
Die genaue (best practice) Vorgehensweise ist aber in der MSDN durchaus
angedeutet.


So, das sind die aller gröbsten Hauptsachen - wenn es daran nicht liegt,
muss man sicher genauer die Konfiguration ansehen.


ciao Frank
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET

Ähnliche fragen