2008-12-30 14 views
5

ont pas vu beaucoup de Genève relatives aux questions encore, j'ai posté cette question dans le Geneva Forum et ...Création d'un cache de jeton local en utilisant le cadre de Genève

Je travaille sur un scénario où nous avons une gagner des applications app avec une base d'installation large, qui émettra des appels fréquents à divers services hébergés par nous centralement tout au long de son fonctionnement.

Les services utilisent tous le Cadre de Genève et tous les clients devraient appeler notre STS première à émettre avec un jeton pour permettre l'accès aux services. En utilisant le ws2007FederationHttpBinding, l'application peut être configurée pour récupérer un jeton du STS avant chaque appel de service, mais évidemment ce n'est pas la manière la plus efficace car nous faisons presque double emploi avec l'appel de prestations de service. J'ai également implémenté le code requis pour récupérer le jeton "manuellement" de l'application, puis passer le même jeton pré-récupéré lors de l'appel des opérations sur les services (basé sur l'exemple WSTrustClient et sur le forum); Cela fonctionne bien et nous avons donc une solution, mais je crois qu'elle n'est pas très élégante car elle nécessite de construire le canal WCF dans le code, en s'éloignant de la merveilleuse configuration WCF. Je préfère de loin l'approche ws2007FederationHttpBinding où le client appelle simplement le service comme n'importe quel autre service WCF, sans rien savoir de Genève, et les liaisons s'occupent de l'échange de jetons.

Alors quelqu'un (Simpson Jon) m'a donné [ce que je pense est] une bonne idée - ajouter un service hébergé dans l'application elle-même pour mettre en cache des jetons récupérés localement. Le service de mémoire cache local appliquerait le même contrat que le service STS; quand receiveing ​​une demande, il vérifierait si un jeton cahced existe, et si oui reviendrait, sinon il appellerait les « vrais » STS, retrive un nouveau jeton, le cache et le retourner. L'application client pourrait alors utiliser encore ws2007FederationHttpBinding, mais au lieu d'avoir les STS que l'émetteur aurait le cache local;

De cette façon, je pense que nous pouvons obtenir le meilleur des deux mondes - la mise en cache des jetons sans le code personnalisé service sepcific; notre cache devrait être capable de gérer les jetons pour tous les RPs.

J'ai créé un prototype très simple pour voir si cela fonctionne, et - un peu pas surprenant malheureusement - je suis un peu coincé -

Mon service local (actuellement une application de la console) reçoit la demande, et - première fois around - appelle le STS pour récupérer le jeton, le met en cache et le renvoie avec succès au client qui, par la suite, l'utilise pour appeler le RP. tout fonctionne bien.

deuxième fois autour, cependant, mon service cahce locale essaie d'utiliser à nouveau le même ordre d'idées, mais le côté client échoue avec un MessageSecurityException -.

« processeur de sécurité n'a pas pu trouver un en-tête de sécurité dans le message Cette Cela peut être dû au fait que le message est une erreur non sécurisée ou qu'il existe une incompatibilité entre les parties de la communication, ce qui peut se produire si le service est configuré pour la sécurité et que le client n'utilise pas la sécurité.

Y at-il quelque chose empêchant la même façon à utiliser plus d'une fois? J'en doute parce que quand j'ai réutilisé le jeton selon l'échantillon WSTrustClient, ça a bien marché; Qu'est-ce que je rate? mon idée est-elle possible? un bon?

est ici le (très basique, à ce stade) bits de code principal du cache local -

static LocalTokenCache.STS.Trust13IssueResponse cachedResponse = null; 
    public LocalTokenCache.STS.Trust13IssueResponse Trust13Issue(LocalTokenCache.STS.Trust13IssueRequest request) 
    { 
     if (TokenCache.cachedResponse == null) 
     { 
      Console.WriteLine("cached token not found, calling STS"); 
      //create proxy for real STS 
      STS.WSTrust13SyncClient sts = new LocalTokenCache.STS.WSTrust13SyncClient(); 
      //set credentials for sts 
      sts.ClientCredentials.UserName.UserName = "Yossi"; 
      sts.ClientCredentials.UserName.Password = "[email protected]"; 
      //call issue on real sts 
      STS.RequestSecurityTokenResponseCollectionType stsResponse = sts.Trust13Issue(request.RequestSecurityToken); 
      //create result object - this is a container type for the response returned and is what we need to return; 
      TokenCache.cachedResponse = new LocalTokenCache.STS.Trust13IssueResponse(); 
      //assign sts response to return value... 
      TokenCache.cachedResponse.RequestSecurityTokenResponseCollection = stsResponse; 
     } 
     else 
     { 
     } 
     //...and reutn 
     return TokenCache.cachedResponse; 

Répondre

6

C'est presque embarrassant, mais grâce à Dominick Baier sur le forum, je ne réalise maintenant que je l'ai manqué un point énorme (je savais que cela n'avait pas de sens! honnêtement! :-)) -

Un jeton est récupéré une fois par proxy de service, en supposant qu'il n'avait pas expiré, et donc tout ce que je devais faire est de réutiliser le même proxy, que je projetais de faire de toute façon, mais, plutôt stupidement, n'a pas sur mon prototype. En outre, j'ai trouvé un échantillon très intéressant sur les échantillons MSF WCF - Durable Issued Token Provider, qui, si je comprends bien, utilise un comportement de point de terminaison personnalisé côté client pour implémenter la mise en cache des jetons, ce qui est très élégant.

Je vais encore examiner cette approche car nous avons plusieurs services et nous pourrions ainsi atteindre encore plus d'efficacité en réutilisant le même jeton entre leurs proxys.

Donc - deux solutions, à peu près infornt de mes yeux; J'espère que ma stupidité aide quelqu'un à un moment donné!

+0

rien ici est stupide - si l'on tombe dans cet espace alors il y aura plus. Up vous a voté sur la question et la réponse pour y revenir. ouais pour toi. –

+0

de même - croyez-le ou pas un scénario similaire. Sympa pour revenir – Sentinel