Pregunta

Estoy intentando solicitar un recurso HTTP que requiere encabezados de autorización básicos desde una aplicación Adobe AIR. Intenté agregar manualmente los encabezados a la solicitud, así como también usar el método setRemoteCredentials () para establecerlos, sin éxito.

Aquí está el código:

<mx:Script>
    <![CDATA[
        import mx.rpc.events.ResultEvent;
        import mx.rpc.events.FaultEvent;

        private function authAndSend(service:HTTPService):void
        {
            service.setRemoteCredentials('someusername', 'somepassword');
            service.send();
        }

        private function resultHandler(event:ResultEvent):void
        {
            apiResult.text = event.result.toString();
        }

        private function resultFailed(event:FaultEvent):void
        {
            apiResult.text = event.fault.toString();
        }
    ]]>
</mx:Script>

<mx:HTTPService id="apiService"
    url="https://mywebservice.com/someFileThatRequiresBasicAuth.xml"
    resultFormat="text"
    result="resultHandler(event)"
    fault="resultFailed(event)" />

<mx:Button id="apiButton"
    label="Test API Command"
    click="authAndSend(apiService)" />

<mx:TextArea id="apiResult" />

Sin embargo, sigue apareciendo un cuadro de diálogo de autenticación básica estándar que solicita al usuario su nombre de usuario y contraseña. Tengo la sensación de que no estoy haciendo esto de la manera correcta, pero toda la información que pude encontrar (documentos Flex, blogs, Google, etc.) no funcionó o fue demasiado vaga para ayudar.

¿Alguna magia negra, oh gurús Flex? Gracias.


EDITAR: Cambiar setRemoteCredentials () a setCredentials () produce el siguiente error de ActionScript:

[MessagingError message='Authentication not supported on DirectHTTPChannel (no proxy).']

EDITAR: Problema resuelto, después de cierta atención de Adobe. Vea las publicaciones a continuación para obtener una explicación completa. Este código funcionará para los encabezados de autenticación HTTP de longitud arbitraria.

import mx.utils.Base64Encoder;
private function authAndSend(service:HTTPService):void
{
        var encoder:Base64Encoder = new Base64Encoder();
        encoder.insertNewLines = false; // see below for why you need to do this
        encoder.encode("someusername:somepassword");

        service.headers = {Authorization:"Basic " + encoder.toString()};                                                
        service.send();
}
¿Fue útil?

Solución

Finalmente recibí algo de atención de Adobe y obtuve una respuesta al respecto. El problema con los encabezados de autenticación HTTP largos es que, de forma predeterminada, la clase Base64Encoder inyectará caracteres de nueva línea cada 72 caracteres. Obviamente, eso hace que un fragmento de la cadena codificada en base 64 se interprete como un nuevo atributo de encabezado, lo que provoca el error.

Puede solucionar esto configurando (en el ejemplo anterior) encoder.insertNewLines = false; La configuración predeterminada es verdadera.

He arreglado el código anterior para que funcione para cadenas de autenticación arbitrariamente largas.

Otros consejos

Ah. El dolor, el sufrimiento. La pura miseria.

Si bien ha descubierto cómo agregar un encabezado antes de hacer su llamada, la verdad desagradable es que en algún lugar en el fondo del espacio de integración de Flash / navegador sus encabezados se están eliminando nuevamente.

De mi blog el año pasado en verveguy.blogspot.com

Así que he descifrado la Verdad. (Yo creo que) Es más torturado de lo que uno podría imaginar

1 / Todas las solicitudes HTTP GET están desprovistas de encabezados. No está en la pila Flex, por lo que probablemente sea el tiempo de ejecución subyacente de Flash Player

2 / Todas las solicitudes HTTP GET que tienen un tipo de contenido distinto de application/x-www-form-urlencoded se convierten en solicitudes POST

3 / Todas las solicitudes HTTP POST que no tienen datos publicados reales se convierten en solicitudes GET. Ver 1 / y 2 /

4 / Todas las solicitudes HTTP PUT y HTTP DELETE se convierten en solicitudes POST. Esto parece ser una limitación del navegador con la que el reproductor Flash está atascado. (?)

Lo que se reduce a esto en términos prácticos es que si desea pasar encabezados en todas las solicitudes, siempre debe usar POST y debe encontrar otra forma de comunicar la semántica de la operación que " realmente quería < !> quot ;. La comunidad de Rails se ha decidido a pasar ?_method=PUT/DELETE como una solución para los problemas del navegador subyacentes a 4 /

Dado que Flash agrega el maravilloso dolor de eliminación de encabezado en GET, también estoy usando ?_method=GET como solución para eso. Sin embargo, dado que esto se dispara en 3 /, Estoy pasando un objeto ficticio como los datos POST codificados. Lo que significa que mi servicio debe ignorar los datos falsos publicados en una <=> solicitud.

Crucial en este punto para saber sobre 2 /. Eso desperdició un montón de mi tiempo.

He incorporado todo este manejo en una nueva clase de servicio RESTS con soporte de marcado MXML, por lo que es posible pretender que esto no existe en el lado del cliente.

Espero que esto ayude a alguien.

El setCredentials () & amp; Los métodos setRemoteCredentials () están diseñados para su uso con Flex / LiveCycle Data Services, por lo que probablemente no se apliquen en su caso.

Esto debería funcionar para usted. Pude reproducir este comportamiento en mi servidor, y esta solución parece haber funcionado; todavía parece un poco extraño, esto no es más fácil de usar para la API, teniendo en cuenta lo común que sería un caso de uso, pero no obstante, he probado y verificado que funciona, dado un certificado SSL válido:

private function authAndSend(service:HTTPService):void
{
        var encoder:Base64Encoder = new Base64Encoder();
        encoder.encode("someusername:somepassword");

        service.headers = {Authorization:"Basic " + encoder.toString()};                            
        service.send();
}

¡Espero que ayude! Y gracias por publicar, estoy seguro de que me habría encontrado con este tarde o temprano. ;)

¡Esto realmente me ha ayudado! ¡Gracias! Yo uso Flex Builder 3

Una nota: los encabezados de propiedad de WebService son de solo lectura. Así que traté de usar httpHeaders. ¡Funciona!

    var encoder:Base64Encoder = new Base64Encoder();
    encoder.insertNewLines = false;
    encoder.encode("test:test");

    sfWS.httpHeaders = {Authorization:"Basic " + encoder.toString()};   

Tuve el mismo problema al consumir el servicio web de autenticación básica HTTP. Esta es mi solución; funciona bien:

private function authAndSend(service:WebService):void
{
    var encoder:Base64Encoder = new Base64Encoder();
        encoder.insertNewLines = false; 
        encoder.encode("user:password");
    service.httpHeaders = { Authorization:"Basic " + encoder.ToString() };
    service.initialize();
}

uso

authAndSend(WebService( aWebServiceWrapper.serviceControl));

Intente usar setCredentials en lugar de setRemoteCredentials y, en su defecto, use Fiddler / Charles para averiguar qué encabezados se envían con la solicitud.

Además, solo para que otras personas no pasen 10 minutos averiguando por qué el ejemplo correcto no funciona del todo bien, debe importar el paquete mx.utils.Base64Encoder, por ejemplo:

        import mx.utils.Base64Encoder;

Al principio o en algún lugar dentro del área CDATA. Soy nuevo en flex, así que al principio no era tan obvio.

Así es como se hace.

import mx.utils.Base64Encoder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.HTTPService;

var _oHttp:HTTPService = new HTTPService;
var sUsername:String = "theusername"
var sPassword:String = "thepassword";

var oEncoder:Base64Encoder = new Base64Encoder(); 
oEncoder.insertNewLines = false; 
oEncoder.encode(sUsername + ":" + sPassword); 

_oHttp.method = "POST";
_oHttp.headers = {Authorization:"Basic " + oEncoder.toString()}; 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top