2009-02-03 9 views
10

Tengo un script de carga de archivos Flex que utiliza URLRequest para cargar archivos en un servidor. Quiero agregar soporte para la autenticación http (directorios protegidos con contraseña en el servidor), pero no sé cómo implementar esto, supongo que necesito extender la clase de alguna manera, pero sobre cómo estoy un poco perdido.Flex 3: cómo admitir la autenticación HTTP URLRequest?

Intenté modificar lo siguiente (reemplazando HTTPService con URLRequest), pero eso no funcionó.

private function authAndSend(service:HTTPService):void{   
    var encoder:Base64Encoder = new Base64Encoder();   
    encoder.encode("someusername:somepassword");   
    service.headers = {Authorization:"Basic " + encoder.toString()}; 
    service.send(); 
} 

Debo señalar que no estoy bien informado cuando se trata de ActionScript/Flex, aunque he logrado modificar satisfactoriamente el script de carga un poco.

[Editar] - aquí es una actualización de mi progreso, basado en la respuesta a continuación, aunque todavía no puedo conseguir que esto funcione:

Gracias por su ayuda. Intenté implementar tu código, pero no tuve suerte.

El comportamiento general que estoy experimentando al tratar con ubicaciones autenticadas HTTP es que con IE7 todo está bien, pero en Firefox cuando intento subir un archivo al servidor muestra un mensaje de autenticación HTTP, que incluso si se da el correcto detalles, simplemente detiene el proceso de carga.

Creo que la razón por la cual IE7 está bien es por la información de sesión/autenticación compartida por el navegador y el componente Flash; sin embargo, en Firefox este no es el caso y experimento el comportamiento anterior.

Aquí es mi función de carga actualizada, incorporando los cambios:

private function pergress():void 
{ 
if (fileCollection.length == 0) 
    { 
    var urlString:String = "upload_process.php?folder="+folderId+"&type="+uploadType+"&feid="+formElementId+"&filetotal="+fileTotal; 
    if (ExternalInterface.available) 
    { 
    ExternalInterface.call("uploadComplete", urlString); 
    } 
    } 
if (fileCollection.length > 0) 
    { 
    fileTotal++; 
    var urlRequest:URLRequest = new URLRequest("upload_file.php?folder="+folderId+"&type="+uploadType+"&feid="+formElementId+"&obfuscate="+obfuscateHash+"&sessidpass="+sessionPass); 
    urlRequest.method = URLRequestMethod.POST; 
    urlRequest.data = new URLVariables("name=Bryn+Jones"); 
    var encoder:Base64Encoder = new Base64Encoder(); 
    encoder.encode("testuser:testpass"); 
    var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoder.toString()); 
    urlRequest.requestHeaders.push(credsHeader); 

    file = FileReference(fileCollection.getItemAt(0)); 
    file.addEventListener(Event.COMPLETE, completeHandler); 
    file.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHTTPStatus); 
    file.addEventListener(ProgressEvent.PROGRESS, onUploadProgress); 
    file.upload(urlRequest); 
    } 
} 

Como se mencionó anteriormente, que parecen estar experimentando los mismos resultados con o sin las enmiendas a mi función.

¿Puedo preguntar también dónde se debe ubicar crossdomain.xml, ya que actualmente no tengo uno y no estoy seguro de dónde ubicarlo?

+0

crossdomain.xml debe ser colocado en el directorio raíz de la aplicación web. Por lo tanto, si los archivos que comprenden www.yoursite.com se encuentran en D: \ websites \ yoursite.com, la ruta del archivo debe ser d: \ sites \ yoursite.com \ crossdomain.xml. –

+0

Además de colocar su archivo corssdomain.xml (lo cual debe hacer), ¿sabe qué versión de Flash Player tiene instalada? ¿Te aseguraste de estar usando Flash Player 10? (Parece que mis resultados fueron que Flash Player 9 no juega bien con los encabezados de Autorización personalizados.) –

+0

Gracias por su ayuda Christian - lamentablemente, no he tenido la oportunidad de realizar más pruebas (se han visto inundadas con otro proyecto) pero intentaré uno, tengo la oportunidad. – BrynJ

Respuesta

18

La sintaxis es un poco diferente para URLRequest, pero la idea es la misma:

private function doWork():void 
{ 
    var req:URLRequest = new URLRequest("http://yoursite.com/yourservice.ext"); 
    req.method = URLRequestMethod.POST; 
    req.data = new URLVariables("name=John+Doe"); 

    var encoder:Base64Encoder = new Base64Encoder();   
    encoder.encode("yourusername:yourpassword"); 

    var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoder.toString()); 
    req.requestHeaders.push(credsHeader); 

    var loader:URLLoader = new URLLoader(); 
    loader.load(req); 
} 

Un par de cosas a tener en cuenta:

  • mejor que puedo decir, por alguna razón , esto solo funciona cuando el método de solicitud es POST; los encabezados no se configuran con las solicitudes GET.

  • Curiosamente, también falla a menos que al menos un par de nombre-valor URLVariables se empaquete con la solicitud, como se indicó anteriormente. Es por eso que muchos de los ejemplos que ves por ahí (incluido el mío) adjuntan "name = John + Doe" - es solo un marcador de posición para algunos datos que parece requerir URLRequest al configurar cualquier encabezado HTTP personalizado. Sin él, incluso una solicitud POST debidamente autenticada también fallará.

  • Al parecer, Flash Player versión 9.0.115.0 bloquea completamente todos los encabezados de autorización (más información sobre éste here), por lo que probablemente querrá mantener esto en mente, también.

  • Seguramente tendrá que modificar su dominio cruzado.archivo xml para acomodar los encabezados que va a enviar. En mi caso, estoy usando esto, que es un archivo de política bastante abierto en el sentido de que acepta desde cualquier dominio, por lo que en su caso, es posible que desee limitar las cosas un poco más, dependiendo de qué tan consciente esté de la seguridad. .

crossdomain.xml:

<?xml version="1.0"?> 
<cross-domain-policy> 
    <allow-access-from domain="*" /> 
    <allow-http-request-headers-from domain="*" headers="Authorization" /> 
</cross-domain-policy> 

... y que parece funcionar; más información sobre este está disponible en Adobe here).

El código anterior se probó con Flash Player 10 (con archivos SWF de depuración &), por lo que debería funcionar para usted, pero quería actualizar mi publicación original para incluir toda esta información adicional en caso de que tenga algún problema, ya que las posibilidades parecen (tristemente) probable que lo haga.

Espero que ayude! Buena suerte. Voy a estar atento a los comentarios.

+0

Tonos de consejos para lo mismo, pero la única respuesta de trabajo real que funciona para la aplicación flexible simple con sdk 4.6. Muchas gracias. – serkan

+0

esto funciona con as3 ide también gracias. – sputn1k

1

No estoy seguro de esto, pero ¿ha intentado agregar el nombre de usuario: contraseña @ al comienzo de su url?

"http://username:[email protected]/yourservice.ext"

+0

Usar esta parece ser la única manera de enviar información de autorización usando una solicitud GET – Arpit

+0

Claramente, este es un hilo viejo, pero simplemente arrojando por ahí que este método de agregar 'username: password @ ...' funcionó para mí, mientras que agregar los encabezados de autenticación básica no funcionó sin mostrar los diálogos de autenticación en mi aplicación de AIR. – dierdre

0

problema aparentemente similares se resolvió here. Le insto a que también verifique el Flexcoders post vinculado en la primera publicación.

El problema fue que FireFox utiliza una instancia de ventana del navegador por separado para enviar la solicitud de carga del archivo. La solución consiste en adjuntar manualmente el ID de sesión a la url de solicitud. El ID de la sesión no está adjuntado como una variable GET normal, pero con un punto y coma (el motivo de esta sintaxis es desconocido para mí).

+0

Me encontré con este problema de sesión también, y se me ocurrió una solución similar, pero este no es el problema que se plantea aquí, que es específicamente la autenticación HTTP (no relacionada con la sesión como tal). – BrynJ

0

Flash es muy limitado en términos de qué tipo de encabezados puede pasar con una solicitud http (y cambia entre navegadores y sistemas operativos). Si logras que esto funcione en un navegador/sistema operativo, asegúrate de probarlo en los demás.

Lo mejor que puede hacer es no meterse con los encabezados HTTP.

Tenemos el mismo problema (cargando en Álbumes web de Picasa desde el flash) y publicamos a través de un proxy en nuestro servidor. Pasamos los encabezados adicionales como parámetros de publicación y nuestro proxy hace lo correcto.

1
var service : HTTPService = new HTTPService(); 
var encoder:Base64Encoder = new Base64Encoder(); 
encoder.insertNewLines = false; 
encoder.encode("user:password"); 

service.headers = {Authorization:"Basic " + encoder.toString()}; 
service.method = HTTPRequestMessage.POST_METHOD; 
service.request = new URLVariables("name=John+Doe"); 
service.addEventListener(FaultEvent.FAULT,error_handler); 
service.addEventListener(ResultEvent.RESULT,result_handler); 
service.url = 'http://blah.blah.xml?'+UIDUtil.createUID(); 
service.send(); 
+0

Hola chicos, gracias por sus ideas, me las arreglo para hackear el uso de HTTPService en lugar de URLRequest. Todo lo que hice fue agregar variable a través de un service.request y establecer service.method = 'POST' Espero que ayuden !!! :) –

0

Aquí es un trabajo en torno al utilizar ASP.Net basada en parte en el trabajo here.

Creé un componente que escribe dinámicamente objetos Flex en la página para que puedan ser utilizados en UpdatePanels. Envíame un mensaje si quieres que codifiquen.Para resolver el problema anterior en páginas donde las cookies de autenticación necesitarán ser enviadas por URLRequest, agrego los valores en flashVars.

Este código sólo funciona en mi objeto, pero se entiende la idea

Dictionary<string, string> flashVars = new Dictionary<string, string>();  
flashVars.Add("auth", Request.Cookies["LOOKINGGLASSFORMSAUTH"].Value); 
flashVars.Add("sess", Request.Cookies["ASP.NET_SessionId"].Value); 
myFlexObject.SetFlashVars(flashVars); 

A continuación, en el objeto de Flex, la verificación de los parametros

if (Application.application.parameters.sess != null) 
    sendVars.sess= Application.application.parameters.sess; 
if (Application.application.parameters.auth != null) 
    sendVars.au= Application.application.parameters.auth; 

request.data = sendVars; 
request.url = url; 
request.method = URLRequestMethod.POST; 

Finalmente meter las galletas en el Global.asax BeginRequest

if (Request.RequestType=="POST" && Request.Path.EndsWith("upload.aspx")) 
{ 
    try 
    { 
     string session_param_name = "sess"; 
     string session_cookie_name = "ASP.NET_SESSIONID"; 
     string session_value = Request.Form[session_param_name]; // ?? Request.QueryString[session_param_name]; 
     if (session_value != null) { UpdateCookie(session_cookie_name, session_value); } 
    } 
    catch (Exception) { } 

    try 
    { 
     string auth_param_name = "au"; 
     string auth_cookie_name = FormsAuthentication.FormsCookieName; 
     string auth_value = Request.Form[auth_param_name];// ?? Request.QueryString[auth_param_name]; 

     if (auth_value != null) { UpdateCookie(auth_cookie_name, auth_value); } 
    } 
    catch (Exception) { } 

} 

esperanza esta ayuda a alguien a evitar las 6 horas Acabo de pasar frente a este. Adobe ha cerrado el problema como irresoluble, por lo que este fue mi último recurso.

2

Si desea cargar un archivo, solo tiene que enviar los encabezados correctos y el contenido del archivo usando URLRequest a través de la clase UploadPostHelper. Esto funciona al 100%, estoy usando esta clase para subir imágenes generadas y archivos CSV, pero puedes subir cualquier tipo de archivo.

Esta clase simplemente prepara la solicitud con los encabezados y el contenido como si estuviera cargando el archivo desde un formulario html.

http://code.google.com/p/as3asclublib/source/browse/trunk/net/UploadPostHelper.as?r=118

_urlRequest = new URLRequest(url); 
     _urlRequest.data = "LoG"; 
     _urlRequest.method = URLRequestMethod.POST; 

     _urlRequest.requestHeaders.push(new URLRequestHeader("X-HTTP-Code-Override", "true")); 
     _urlRequest.requestHeaders.push(new URLRequestHeader("pragma", "no-cache")); 

     initCredentials(); 
_loader.dataFormat = URLLoaderDataFormat.BINARY; 
      //this creates a security problem, putting the content type in the headers bypasses this problem 
      //_urlRequest.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary(); 
      _urlRequest.requestHeaders.push(new URLRequestHeader('Cache-Control', 'no-cache')); 
      _urlRequest.requestHeaders.push(new URLRequestHeader('Content-Type', 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary())); 
      _urlRequest.data = UploadPostHelper.getPostData("file.csv", param[1]); 

     _loader.load(_urlRequest); 
Cuestiones relacionadas