11
votes

Service de repos de WCF auto-hébergé et authentification de base

J'ai créé un service de repos de WCF auto-hébergé (avec quelques extra de Kit de démarreur de WCF Repos Aperçu 2). Tout cela fonctionne bien.

J'essaie maintenant d'ajouter une authentification de base au service. Mais je frappe des barrages routiers plutôt gros dans la pile de WCF qui m'empêche de le faire.

Il semble que le httplistener (quels services de WCF auto-hébergés utilisent en interne à un niveau bas dans la pile WCF) bloquent mes tentatives d'insérer un www-authentifier En-tête sur un 401 non autorisé auto-généré réponse. Pourquoi?

Je peux obtenir l'authentification fonctionnant si j'oublie de ce www-authentifier en-tête (qu'il semble que Microsoft ait aussi fait). Mais c'est la question. Si je n'envoie pas de www-authentifier en-tête, le navigateur Web ne affiche pas la boîte de dialogue "Logon" standard. L'utilisateur sera simplement confronté à une page d'erreur non autorisé sans aucun moyen de vous connecter réellement.

Les services de repos doivent être accessibles aux ordinateurs et aux humains (au moins au moins sur le niveau de demande d'obtention). Par conséquent, je pense que le repos de la WCF ne respecte pas une partie fondamentale du repos ici. Est-ce que quelqu'un est d'accord avec moi?

Quelqu'un a-t-il une authentification de base travaillant avec un service de repos de WCF auto-hébergé? Si oui, comment l'avez-vous fait?

PS: Évidemment, mes intentions d'utiliser une authentification de base non sécurisée sont sur le principe que j'aurais aussi du travail HTTPS / SSL pour mon service. Mais c'est une autre affaire.

PPS: J'ai essayé WCF Repos apport ( http://wcfrescontrib.codeplex.com/ ) et cela a exactement le même problème. Il semble que cette bibliothèque n'a pas été testée dans des scénarios auto-hébergés.

merci.


0 commentaires

3 Réponses :


13
votes

Malheureusement, j'ai déterminé (en analysant le code source de référence de la WCF et l'aide de l'outil Fiddler pour la session HTTP reniflant) selon lequel il s'agit d'un bogue dans la pile de WCF.

Utilisation de FIDDLER, j'ai remarqué que mon service WCF était Se comporter Contrairement à tout autre site Web utilisant l'authentification de base.

Pour être clair, c'est ce qui devrait arriver:

  1. Navigateur envoie obtenir sans savoir qu'un mot de passe est même nécessaire.
  2. Web Server rejette la demande avec un 401 non autorisé et inclut un www-authentifier en-tête contenant des informations sur des méthodes d'authentification acceptables.
  3. Le navigateur invite l'utilisateur à entrer des informations d'identification.
  4. Le navigateur renvoie obtenir demande et inclut l'authentification appropriée en-tête avec les informations d'identification.
  5. Si les informations d'identification étaient correctes, le serveur Web répond avec 200 OK et la page Web. Si les informations d'identification ont eu tort, le serveur Web répond avec 401 non autorisé et inclut le même www-authentifier en-tête qu'il a fait à l'étape 2.

    Qu'est-ce qui se passait réellement avec mon service WCF était ceci:

    1. Navigateur envoie obtenir sans savoir qu'un mot de passe est même nécessaire.
    2. Avis WCF Il n'y a pas d'authentification d'en-tête de la requête et rejette aveuglément la demande avec un statut non autorisé (code> non autorisé et inclut un www-authentifier en-tête . Tout normal jusqu'à présent.
    3. Navigateur invite l'utilisateur pour les informations d'identification. Toujours normal.
    4. Le navigateur renvoie obtenir demande, y compris l'authentification approprié en-tête.
    5. Si les informations d'identification étaient correctes, le serveur Web répond avec 200 OK . Tout est bon. Si les informations d'identification étaient mauvaises cependant, WCF répond avec 403 interdit et n'inclut pas d'en-têtes supplémentaires tels que www-authentifier . .

      Lorsque le navigateur obtient le statut 403 interdit Il ne perçoit pas que cela soit une tentative d'authentification défaillante. Ce code d'état est destiné à informer le navigateur que l'URL qu'elle a essayé d'accéder est hors limites. Cela ne concerne aucune authentification. Cela a le terrible côté affectant que lorsque l'utilisateur tape mal que son nom d'utilisateur / mot de passe de manière incorrecte (et le serveur rejette avec 403), le navigateur Web ne reppompte pas l'utilisateur à saisir à nouveau leurs informations d'identification. En fait, le navigateur Web croit que l'authentification a réussi et stocke donc ces informations d'identification pour le reste de la session!

      Dans cet esprit, j'ai recherché des éclaircissements:

      Le RFC 2617 ( http://www.faqs.org/rfcs/rfc2617.html#ixzz0eboufnrl ) Ne mentionne nulle part l'utilisation du code d'état interdit . En fait, ce qu'il faut dire sur la question est le suivant:

      Si le serveur d'origine ne souhaite pas accepter les informations d'identification envoyées avec un demande, il devrait renvoyer un 401 (Non autorisée) réponse. La réponse Doit inclure un en-tête www-authentifier champ contenant au moins un Défi (éventuellement nouveau) applicable à la ressource demandée.

      WCF ne fait aucun de ces. Il n'envoie pas correctement un code d'état non autorisé non autorisé. Il n'inclut pas non plus un www-authentifier en-tête.

      MAINTENANT pour trouver le pistolet fumant dans le code source WCF:

      J'ai découvert que dans le HTTPequestContext La classe est une méthode appelée ProcessAuthentication , qui contient les éléments suivants (extrait): xxx

      Je défends Microsoft sur beaucoup de choses, mais c'est indéfendable.

      Heureusement, je l'ai eu de travailler à un niveau "acceptable". Cela signifie simplement que si l'utilisateur entre accidentellement dans son nom d'utilisateur / mot de passe de manière incorrecte, le seul moyen d'obtenir une autre tentative est de fermer complètement leur navigateur Web et de le redémarrer pour réessayer. Tous parce que WCF est pas répondant à la tentative d'authentification défaillante avec un 401 non autorisé et a www-authentifier en-tête selon la spécification.


2 commentaires

@Serialseb Je n'avais pas le cœur de lui dire que j'ai abandonné la tentative de résoudre les problèmes d'authentification sur la WCF et allé directement à HTTplistener.


Cheers Guys :) Darrel, j'ai vu vos commentaires dans une autre discussion et me croire que je l'ai considéré comme une option. Heureusement, nous n'avons pas encore investi trop dans la WCF. Donc, nous pouvons aller de l'avant et le fossé.



6
votes

J'ai trouvé la solution basée sur cette link et Ceci .

Le premier consiste à remplacer la méthode de validation dans une classe appelée CustomUsernameValidator B> Hérités de Système.IdidentityModel.Selectors.SernamePasswordValidator B>: P>

<bindings>
  <webHttpBinding>
    <binding name="basicAuthBinding">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic" realm=""/>
      </security>
    </binding>
  </webHttpBinding>
</bindings>

<service behaviorConfiguration="SimpleServiceBehavior" name="Service.webService">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8000/webService" />
      </baseAddresses>
    </host>
    <endpoint address="http://localhost:8000/webService/restful" binding="webHttpBinding" bindingConfiguration="basicAuthBinding" contract="Service.IwebService" behaviorConfiguration="HttpEnableBehavior"/>
</service>


0 commentaires

1
votes

Oui, vous pouvez fournir une authentification de base pour les services WCF basés sur le repos. Cependant, il y a plusieurs étapes que vous devez suivre pour avoir une solution complète et sécurisée et jusqu'à présent, la plupart des réponses sont des fragments de toutes les pièces nécessaires.

  1. Configurez votre service auto-hébergé pour avoir un certificat SSL lié au port que vous hébergez votre service WCF sur. Ceci est très différent de l'application d'un certificat SSL lors de l'utilisation de l'hébergement géré à travers quelque chose comme IIS. Vous devez appliquer le certificat SSL à l'aide d'un utilitaire de ligne de commande. Vous NE PAS VOUS NOUVEZ UTILISER Authentification de base sur un service de repos sans à l'aide de SSL car les informations d'identification de l'en-tête sur non sécurisée. Voici (2) messages détaillés que j'ai écrites sur exactement comment faire cela. Votre question est trop grosse pour avoir tous les détails sur un poste de forum, c'est pourquoi je fournis les liens avec des détails complets et des instructions étape par étape:

    Appliquer et utiliser un Certificat SSL avec un service de WCF auto-hébergé

    Création d'une WCF Service et sécurisez-le à l'aide de HTTPS sur SSL

  2. Configurez votre service pour utiliser l'authentification de base. Ceci est une solution de plusieurs parties également. 1er configure votre service pour utiliser l'authentification de base. La seconde consiste à créer un "CustomsusNamePasswordPasswordSadvalidatType" et inspecter les informations d'identification pour authentifier le client. Je vois que le dernier message a été échappé à cela, mais il a fait pas HTTPS et n'est qu'une très petite partie de la solution; Faites attention aux directives qui ne sont pas à condition une solution de bout en bout incluant la configuration et sécurité. La dernière étape consiste à examiner le contexte de sécurité pour fournir une autorisation au niveau de la méthode si nécessaire. Le message suivant que j'ai écrit vous emmène étape par étape sur la configuration, authentifier, et autoriser vos clients.

    Services reposants: authentifiant les clients utilisant l'authentification de base

    Il s'agit de la solution de bout en bout nécessaire à l'utilisation d'une authentification de base avec des services de WCF auto-hébergés.


0 commentaires