Добавление и получение данных из контекста запроса - PullRequest
5 голосов
/ 06 октября 2011

Я пытаюсь прикрепить ключ API к заголовку исходящего сообщения OperationContext следующим образом:

    public static void AddApikeyToHeader(string apikey, IContextChannel channel, string address)
    {
        using (OperationContextScope scope = new OperationContextScope(channel))
        {
            MessageHeader header = MessageHeader.CreateHeader("apikey", address, apikey);
            OperationContext.Current.OutgoingMessageHeaders.Add(header);

        }
    }

, но тогда я не знаю, как получить заголовок на стороне сервера.Я использую диспетчер авторизации службы, и я получаю текущий рабочий контекст и пытаюсь получить заголовок следующим образом:

    public string GetApiKey(OperationContext operationContext)
    {
        var request = operationContext.RequestContext.RequestMessage;

        var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];

        return prop.Headers["apikey"];
    }

, но там нет прикрепленного заголовка apikey.Кроме того, при отладке, когда я проверяю OperationContext, я не вижу нигде моего заголовка apikey.Кто-нибудь может увидеть, где я иду не так?

Ответы [ 3 ]

14 голосов
/ 10 октября 2011

Пользовательский заголовок можно добавить следующим образом:

using (ChannelFactory<IMyServiceChannel> factory = 
       new ChannelFactory<IMyServiceChannel>(new NetTcpBinding()))
      {
       using (IMyServiceChannel proxy = factory.CreateChannel(...))
       {
          using ( OperationContextScope scope = new OperationContextScope(proxy) )
          {
             Guid apiKey = Guid.NewGuid();
             MessageHeader<Guid> mhg = new MessageHeader<Guid>(apiKey);
             MessageHeader untyped = mhg.GetUntypedHeader("apiKey", "ns");
             OperationContext.Current.OutgoingMessageHeaders.Add(untyped);

             proxy.DoOperation(...);
          }
       }                    
    }

А на стороне обслуживания вы можете получить заголовок, например:

Guid apiKey = 
OperationContext.Current.IncomingMessageHeaders.GetHeader<Guid>("apiKey", "ns");
1 голос
/ 10 октября 2011

Я предполагаю, что вы пытаетесь использовать свой сервис, используя некоторый транспорт на основе протокола Http (SOAP, REST и т. Д.).Я также предполагаю, что вам нужно авторизовать абонента, используя предоставленный ключ API.Если оба этих условия применимы к вашему вопросу, вы можете читать дальше.

Недавно мне пришлось решать аналогичную проблему только из-за того, что я не передавал ключ API, а использовал комбинацию имени пользователя и пароля с использованием некоторых пользовательских заголовков HTTP,В конечном итоге я решил эту проблему, внедрив специальную политику авторизации, которая когда-то была настроена в Web.config, аккуратно подключена к конвейеру WCF.

Фрагмента, приведенного ниже, должно быть достаточно для начала работы.Возможно, вам придется заменить заголовки x-ms-credentials-XXX на один, представляющий ваш ключ API.

internal class RESTAuthorizationPolicy : IAuthorizationPolicy
{
  public RESTAuthorizationPolicy()
  {
    Id = Guid.NewGuid().ToString();
    Issuer = ClaimSet.System;
  }

  public bool Evaluate(EvaluationContext evaluationContext, ref object state)
  {
    const String HttpRequestKey = "httpRequest";
    const String UsernameHeaderKey = "x-ms-credentials-username";
    const String PasswordHeaderKey = "x-ms-credentials-password";
    const String IdentitiesKey = "Identities";
    const String PrincipalKey = "Principal";

    // Check if the properties of the context has the identities list 
    if (evaluationContext.Properties.Count > 0 ||
      evaluationContext.Properties.ContainsKey(IdentitiesKey) ||
      !OperationContext.Current.IncomingMessageProperties.ContainsKey(HttpRequestKey))
      return false;

    // get http request
    var httpRequest = (HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpRequestKey];

    // extract credentials
    var username = httpRequest.Headers[UsernameHeaderKey];
    var password = httpRequest.Headers[PasswordHeaderKey];

    // verify credentials complete
    if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
      return false;

    // Get or create the identities list 
    if (!evaluationContext.Properties.ContainsKey(IdentitiesKey))
      evaluationContext.Properties[IdentitiesKey] = new List<IIdentity>();
    var identities = (List<IIdentity>) evaluationContext.Properties[IdentitiesKey];

    // lookup user
    using (var con = ServiceLocator.Current.GetInstance<IDbConnection>())
    {
      using (var userDao = ServiceLocator.Current.GetDao<IUserDao>(con))
      {
        var user = userDao.GetUserByUsernamePassword(username, password);

        ...
0 голосов
/ 10 октября 2011

Вы смотрели на этот вопрос: Как добавить собственный заголовок HTTP к каждому вызову WCF? ?Может содержать ваше решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...