2013-12-03 5 views
4

Я использую базовую аутентификацию в своей службе WCF. А также с использованием поставщика членства ASP для аутентификации.Встроенный способ выполнить базовую аутентификацию с помощью службы WCF REST?

Web.Config: Для REST службы:

<webHttpBinding> 
    <binding name="webHttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="200065536" maxBufferPoolSize="200065536" maxReceivedMessageSize="200065536" transferMode="Buffered" useDefaultWebProxy="true"> 
     <readerQuotas maxDepth="202048000" maxStringContentLength="202048000" maxArrayLength="202048000" 
        maxBytesPerRead="202048000" maxNameTableCharCount="202048000"/> 
     <security mode="Transport"> 
     </security> 
    </binding> 
    </webHttpBinding> 

Тип аутентификации и режим:

<serviceCredentials> 
      <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="CustomMemberShipProvider" /> 
</serviceCredentials> 

Мой заказ класс для BasicAuthentication перед вызовом любого метода. Код показан ниже:

namespace BasicAuth.Service 
{ 
    public class BasicAuthenticationInvoker : Attribute, IOperationBehavior, IOperationInvoker 
    { 
     #region Private Fields 

     private IOperationInvoker _invoker; 

     #endregion Private Fields 

     #region IOperationBehavior Members 

     public void ApplyDispatchBehavior(OperationDescription operationDescription, 
              DispatchOperation dispatchOperation) 
     { 
      _invoker = dispatchOperation.Invoker; 
      dispatchOperation.Invoker = this; 
     } 

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

     public void AddBindingParameters(OperationDescription operationDescription, 
             BindingParameterCollection bindingParameters) 
     { 
     } 

     public void Validate(OperationDescription operationDescription) 
     { 
     } 

     #endregion IOperationBehavior Members 

     #region IOperationInvoker Members 

     public object Invoke(object instance, object[] inputs, out object[] outputs) 
     { 
      System.Diagnostics.Debugger.Break(); 
      if (Authenticate()) 
       return _invoker.Invoke(instance, inputs, out outputs); 
      else 
      { 
       outputs = null; 
       return null; 
      } 
     } 

     public object[] AllocateInputs() 
     { 
      return _invoker.AllocateInputs(); 
     } 

     public IAsyncResult InvokeBegin(object instance, object[] inputs, 
             AsyncCallback callback, object state) 
     { 
      throw new NotSupportedException(); 
     } 

     public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result) 
     { 
      throw new NotSupportedException(); 
     } 

     public bool IsSynchronous 
     { 
      get 
      { 
       return true; 
      } 
     } 

     #endregion IOperationInvoker Members 

     private bool Authenticate() 
     { 
      string[] credentials = GetCredentials(WebOperationContext.Current.IncomingRequest.Headers); 

      if (credentials != null && credentials.Length == 2) 
      { 
       var username = credentials[0]; 
       var password = credentials[1]; 
       if (Membership.ValidateUser(username, password)) //if valid user 
       { 
        //get the roles of the user 
        string[] roles = Roles.GetRolesForUser(username); 
        Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity(username), roles); 
        return true; 
       } 
      } 
      WebOperationContext.Current.OutgoingResponse.Headers["WWW-Authenticate"] = string.Format("Basic realm=\"{0}\"", string.Empty); 
      WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Unauthorized; 
      return false; 
     } 

     private string[] GetCredentials(WebHeaderCollection headers) 
     { 
      string credentials = WebOperationContext.Current.IncomingRequest.Headers["Authorization"]; 
      if (credentials != null) 
       credentials = credentials.Trim(); 

      if (!string.IsNullOrEmpty(credentials)) 
      { 
       try 
       { 
        string[] credentialParts = credentials.Split(new[] { ' ' }); 
        if (credentialParts.Length == 2 && credentialParts[0].Equals("basic", StringComparison.OrdinalIgnoreCase)) 
        { 
         credentials = Encoding.ASCII.GetString(Convert.FromBase64String(credentialParts[1])); 
         credentialParts = credentials.Split(new[] { ':' }); 
         if (credentialParts.Length == 2) 
          return credentialParts; 
        } 
       } 
       catch (Exception ex) 
       { 

       } 
      } 

      return null; 
     } 
    } 
} 

Мои IService выглядит, как показано ниже:

Мой заказ класс используется в качестве атрибута в контракте IService

public interface IService1 
    { 
     [OperationContract] 
     [BasicAuthenticationInvoker] //my custom class for authentication 
     [WebGet(UriTemplate = "GetString?userID={userID}", 
      ResponseFormat = WebMessageFormat.Json)] 
     string GetString(string userID); 
    } 

При вызове службы WCF REST с помощью AJAX call, я добавляю заголовок аутентификации в запрос и аутентифицирую пользователя, используя указанный выше класс.

AJAX вызов: Ниже вызов Ajax используется для вызова службы и используется для beforeSend authenticte пользователя перед доступом к услуге.

<script> 
      $(function() { 
       alert("onload"); 
       $.ajax 
        ({ 
         type: "GET", 
         data:jsondata, 
         url: https://localhost:446/BasicAuthService.svc/rest/GetString', 
         cache: false, 
         async: true, 
         crossDomain:true, 
         dataType: "json", 
         contentType: "application/json; charset=utf-8", 
         beforeSend: function (xhr) {        
          xhr.setRequestHeader('Authorization', 'Basic plc2gxMjMk'); 
         }, 
         error: function(jqXHR, exception) 
         { 
          alert(jqXHR.status+" "+exception); 
         } 
        }); 
      }); 
    </script> 

Мой вопрос:

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

Так что мне нужно, Вместо использования пользовательского класса для BasicAuthentication, как я могу аутентифицировать каждый запрос службы? Есть ли Встраиваемая функциональность в WCF для аутентификации входящего запроса?

Заранее спасибо.

ответ

0

Режим безопасности должен указать базовую аутентификацию:

<security mode="Transport"> 
    <transport clientCredentialType="Basic" /> 
</security> 

 Смежные вопросы

  • Нет связанных вопросов^_^