2011-05-03 16 views
5

He estado buscando esto por un par de días.WCF .net 4.0 HTTP Basic Autenticación

Solo intento que un Nombre de usuario/Contraseña pase a mi servicio RESTful usando Autenticaciones HTTP Básicas. ¡Todo lo demás funciona asombrosamente!

Esto es lo que se ve mi web.config como:

<?xml version="1.0"?> 
<configuration> 

    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 

    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"> 
     <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> 
    </modules> 
    </system.webServer> 

    <system.serviceModel> 

    <bindings> 
     <wsHttpBinding> 
     <binding name=""> 
      <security mode="Message"> 
      <message clientCredentialType="UserName" /> 
      </security> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> 

    <standardEndpoints> 
     <webHttpEndpoint> 
     <!-- 
      Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
      via the attributes on the <standardEndpoint> element below 
     --> 
     <standardEndpoint name="" helpEnabled="true" defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="true"/> 
     </webHttpEndpoint> 
    </standardEndpoints> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceCredentials> 
      <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="ParkingPandaREST.CustomUserNameValidator, ParkingPandaREST" /> 
      </serviceCredentials>  
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 


    </system.serviceModel> 

</configuration> 

Entonces creó una clase CustomUserNameValidator que tiene lo siguiente:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace ParkingPandaREST 
{ 
    public class CustomUserNameValidator : System.IdentityModel.Selectors.UserNamePasswordValidator 
    { 
     // This method validates users. It allows in two users, test1 and test2 
     // with passwords 1tset and 2tset respectively. 
     // This code is for illustration purposes only and 
     // must not be used in a production environment because it is not secure.  
     public override void Validate(string userName, string password) 
     { 
      if (null == userName || null == password) 
      { 
       throw new ArgumentNullException(); 
      } 

      if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset")) 
      { 
       // This throws an informative fault to the client. 
       throw new System.ServiceModel.FaultException("Unknown Username or Incorrect Password"); 
       // When you do not want to throw an infomative fault to the client, 
       // throw the following exception. 
       // throw new SecurityTokenException("Unknown Username or Incorrect Password"); 
      } 
     } 
    } 
} 

simplemente estoy ejecutando el servicio en mi máquina local y tratando de alcanzar un punto de quiebre en la clase CustomUserNameValidator pero nunca llega. Por lo tanto, no estoy usando SSL en este momento, simplemente tratando de ingresar el nombre de usuario/contraseña.

Respuesta

4

Aquí está la respuesta que se me ocurrió. Es posible que deba modificarse un poco, pero es el núcleo lo que necesita para hacer el trabajo.

Nota: Desactivar la autenticación básica en IIS

  // Get the Header Authorization Value 
      string headerValue = operationContext.IncomingRequest.Headers[HttpRequestHeader.Authorization]; 
      headerValue = headerValue.Replace("Basic ", ""); 
      headerValue = DecodeBase64String(headerValue); 

      // Get Username and Password 
      string userName = headerValue.Substring(0, headerValue.IndexOf(":")); 
      string password = headerValue.Substring(headerValue.IndexOf(":") + 1, headerValue.Length - userName.Length - 1); 

      // Do Custom Authorization here with the userName and password 

.......

También en este caso es la función DecodeBase64String

public static string DecodeBase64String(string encodedData) 
    { 
     byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData); 
     string returnValue = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes); 
     return returnValue; 
    } 

esperanza que ayudan a algunas otras personas que estaban teniendo el mismo problema - ¡salud!

+3

Yo recomendaría usar Encoding.UTF8.GetString (encodedData) aunque –

+0

¿Dónde puso este código? – jao

1

El enlace predeterminado para el transporte HTTP en WCF 4 es basicHttpBinding. Si convierte su elemento wsHttpBinding a un elemento basicHttpBinding y lo configura para la validación personalizada, entonces su código debería ejecutarse.

+0

Traté de cambiar a y todavía no pude conseguir que llegue al punto de ruptura. ¿Me falta algo más? – Adam

+0

Podría ser que la configuración de su cliente y la configuración del servicio no estén sincronizadas. Además, debe configurar IIS para permitir la autenticación básica de HTTP. La configuración de IIS variará según la versión, pero aquí está la configuración de IIS 7: http://technet.microsoft.com/en-us/library/cc772009(WS.10).aspx –

+0

Esto no funcionará en mi máquina de desarrollo local utilizando VS2010 - ¿Simplemente presionando F5 y teniendo en modo de depuración? – Adam

0

La autenticación básica es un protocolo HTTP. Por lo tanto, es seguridad de transporte, no seguridad de mensajes. Su configuración debe contener este fragmento:

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

Pero incluso si lo hace correctamente, el código personalizado, probablemente no será anunciado. Encontrará más detalles sobre este problema en este blog.

+0

Para gestionar la autenticación básica de mis servicios, utilizo: http://altairiswebsecurity.codeplex.com/ Recibo mis servicios como controlador MVC en lugar de WCF. –

+0

Así que con una nueva versión de WCF no puedes hacer la Autenticación HTTP básica correctamente ... ¡vaya que es terrible! – Adam

+0

@Codo Cant siga su enlace el blog :(estoy teniendo el mismo problema con mi validador personalizado no ejecutando – Dendei