Поведение аутентификации WCF REST - PullRequest
0 голосов
/ 15 февраля 2012

Я хочу иметь возможность аутентифицировать веб-сервис WCF Rest, но я не совсем уверен, как это сделать.Похоже, что многие другие вопросы касаются вещей в .net 3.5 WCF (таких как WebServiceHost2), которые, похоже, больше не существуют.

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

<behaviors>
  <serviceBehaviors>
    <behavior name="PasswordValidator">
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom"
                                customUserNamePasswordValidatorType="MyNamespace.PasswordValidator, MyNamespace"/>
      </serviceCredentials>
    </behavior>
  </serviceBehaviors>
</behaviors>

, однако, так как я использую Rest, я не могу запустить эту конфигурацию поведения на основе web.config.Мне как-то нужно сделать это в моем serviceRoute.

RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(HelloService)));

Кто-нибудь знает, как это сделать, или есть какие-нибудь хорошие учебники по безопасности на основе сообщений с Rest и WCF 4.0?

1 Ответ

0 голосов
/ 16 февраля 2012

Я решил это путем реализации настраиваемого атрибута авторизации, который просматривает два настраиваемых поля, которые я добавил в коллекцию заголовков HTTP.

Кажется, это работает очень хорошо.

public class UserAndPasswordAuthenticationAttribute : Attribute, IOperationBehavior, IParameterInspector
    {
        public void ApplyDispatchBehavior(
            OperationDescription operationDescription,
            DispatchOperation dispatchOperation)
        {
            dispatchOperation.ParameterInspectors.Add(this);
        }

        public void AfterCall(string operationName, object[] outputs,
                              object returnValue, object correlationState)
        {
        }

        public object BeforeCall(string operationName, object[] inputs)
        {
            string username = WebOperationContext.Current
                                   .IncomingRequest.Headers["username"];
            string password = WebOperationContext.Current
                                   .IncomingRequest.Headers["password"];


            if (username != "bob" || password!= "123")
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode =
                    HttpStatusCode.Unauthorized;
                throw new UnauthorizedAccessException("");
            }

            return null;
        }

        public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {
        }

        public void Validate(OperationDescription operationDescription)
        {
        }
    }

Затем я могу просто добавить этот атрибут к методам в моем контракте, чтобы защитить их

...