Question

Est-il possible d'exiger une clé API dans l'URL / ou d'une autre façon de passer le service d'une clé privée afin d'accorder l'accès aux données?

J'ai ce moment ...

using System;
using System.Data.Services;
using System.Data.Services.Common;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Web;
using Numina.Framework;
using System.Web;
using System.Configuration;

[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class odata : DataService {


    public static void InitializeService(DataServiceConfiguration config) {

        config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
        //config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    }

    protected override void OnStartProcessingRequest(ProcessRequestArgs args) {

        HttpRequest Request = HttpContext.Current.Request;
        if(Request["apikey"] != ConfigurationManager.AppSettings["ApiKey"])
            throw new DataServiceException("ApiKey needed");

        base.OnStartProcessingRequest(args);
    }
} 

... Cela fonctionne, mais ce n'est pas parfait parce que vous ne pouvez pas obtenir les métadonnées et découvrir le service à travers le service Ajouter explorateur de référence. Je pourrais vérifier si les métadonnées $ est dans l'URL, mais il semble comme un hack. Y at-il une meilleure façon?

Était-ce utile?

La solution

Je suggère d'utiliser l'en-tête d'autorisation pour passer le apiKey au lieu de passer dans la chaîne de requête. C'est ce qu'il est là et il y a de l'aide à garder les clés api de fichiers journaux.

Je ne pense pas qu'il y ait quelque chose de vraiment mal à vérifier la présence de « métadonnées $ » dans l'URL. Vous écrivez le code côté serveur, et le serveur possède l'espace URI, afin de prendre des décisions en fonction du texte dans l'url de la demande est ce que le serveur est tout au sujet. Vous pouvez utiliser quelque chose comme,

  if (requestUrl.Segments.Last().Replace('/','') != '$metadata') 

au lieu de rechercher la chaîne entière uri, si elle fait sentir moins dégueu!

Autres conseils

On dirait que la technique présentée dans cette vidéo fonctionne bien même dans WCF Data services. Vous créez une sous-classe personnalisée de ServiceAuthorizationManager (voir MSDN ), remplacer CheckAccessCore(), et l'enregistrer dans web.config.

Je l'ai à travailler en passant une clé dans un en-tête HTTP de la requête. Le OperationContext passé à CheckAccessCore ne vous donne pas un moyen de saisir les en-têtes de requête HTTP <> de grève, mais vous pouvez les obtenir via HttpContext.Current.Request.Headers. Vous pouvez alors obtenir l'en-tête appropriée de cette collection et vérifiez cependant vous avez besoin.

Voici l'enregistrement nécessaire web.config:

<system.serviceModel>
  <behaviors>
      <serviceBehaviors>
          <behavior>
              <serviceAuthorization serviceAuthorizationManagerType="FullyQualifiedTypeNameHere, ProjectNameHere" />
          </behavior>
      </serviceBehaviors>
  </behaviors>

Mise à jour: J'ai eu tort d'être en mesure d'obtenir les en-têtes de HttpContext.Current.Request.Headers; HttpContext.Current est nulle lors de l'exécution dans IIS (mais curieusement pas lors du débogage). Au lieu de cela, utilisez WebOperationContext.Current.IncomingRequest.Headers comme par cette question.

Mise à jour 2: HttpContext.Current est nul que lorsque vous n'êtes pas en cours d'exécution WCF en mode ASP.NET compatibilité. Vous pouvez activer ce en ajoutant la ligne suivante à web.config au niveau de l'application dans le nœud system.serviceModel:

<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

Ajoutez aussi ce ci-dessus la mise en œuvre de votre service, si vous avez un service WCF de vanille en cours d'exécution en plus du service ADO.NET:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

Ensuite, vous pouvez obtenir HttpContext.Current.Request.Headers et toutes les autres choses fournies par la classe HttpRequest.

Vous pouvez vérifier le type de demande et laisser appels wsdl passer par la touche api.

Je ne suis pas sûr de ce que vos objectifs sont api mais vous pouvez utiliser un certificat client.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top