Pergunta

Eu tenho um Flex de upload de arquivo de script que usa URLRequest para fazer upload de arquivos para um servidor.Eu gostaria de acrescentar o suporte para autenticação de http (protegido por senha diretórios no servidor), mas eu não sei como implementar isso - eu suponho que eu preciso para estender a classe, de alguma forma, mas como estou um pouco perdido.

Eu tentei modificar o seguinte (substituindo HTTPService com URLRequest), mas que não funcionou.

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

Gostaria de salientar que eu não sou conhecedora do ActionScript / Flex, apesar de eu ter conseguido com sucesso modificar o upload do script um pouco.

[Editar] - aqui é uma atualização do meu progresso, com base na resposta abaixo, embora eu ainda não é possível chegar a este trabalho:

Obrigado por sua ajuda.Eu tentei implementar o seu código, mas não tive sorte nenhuma.

O comportamento geral eu estou experimentando ao lidar com HTTP autenticado locais, é que com o IE7 está tudo bem, mas no Firefox quando eu tentar fazer o upload de um arquivo para o servidor apresenta um HTTP prompt de autenticação - que, mesmo se deu com informações corretas, simplesmente bancas o processo de carregamento.

Acredito que a razão IE7 é ok, é para baixo, para a sessão de informação de autenticação compartilhada pelo browser e Flash componente - no entanto, o Firefox não é o caso e eu experiência acima de comportamento.

Aqui está a minha atualizado a função de upload, incorporando as alterações:

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 dito acima, parece que estou tendo os mesmos resultados com ou sem as alterações para a minha função.

Posso perguntar também onde o crossdomain.xml deve ser localizado - como eu atualmente não tenho um e estou sem saber onde colocá-la.

Foi útil?

Solução

A sintaxe é um pouco diferente para o UrlRequest, mas a ideia é a mesma:

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);
}

Algumas coisas a ter em mente:

  • O melhor que posso dizer, por algum motivo, isso só funciona onde o método de solicitação é postado; Os cabeçalhos não são definidos com solicitações de get.

  • É interessante É por isso que muitos dos exemplos que você vê por aí (incluindo o meu) anexam "Nome = John+Doe" - é apenas um espaço reservado para alguns dados que o URLRequest parece exigir ao definir quaisquer cabeçalhos HTTP personalizados. Sem ele, mesmo uma solicitação de postagem adequadamente autenticada também falhará.

  • Aparentemente, a versão do flash player 9.0.115.0 bloqueia completamente todos os cabeçalhos de autorização (mais informações sobre este aqui), então você provavelmente vai querer ter isso em mente também.

  • Você quase certamente precisará modificar seu arquivo crossDomain.xml para acomodar o (s) cabeçalho (s) que você enviará. No meu caso, estou usando isso, o que é um arquivo de política bastante aberto, pois aceita de qualquer domínio; portanto, no seu caso, você pode querer limitar um pouco mais as coisas, dependendo de como você está preocupado com a segurança .

crossDomain.xml:

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

... e isso parece funcionar; Mais informações sobre este estão disponíveis na Adobe aqui).

O código acima foi testado com o Flash Player 10 (com SWFs de depuração e lançamento), por isso deve funcionar para você, mas eu queria atualizar minha postagem original para incluir todas essas informações extras, caso você se depare com quaisquer problemas, pois as chances parecem (Infelizmente) provável que você vá.

Espero que ajude! Boa sorte. Vou ficar de olho nos comentários.

Outras dicas

Os métodos filereference.upload () e fileReference.Download () não suportam o parâmetro URLRequest.RequestHeaders.

http://livedocs.adobe.com/flex/2/langref/flash/net/urlrequest.html

Se você deseja fazer upload de um arquivo, basta enviar os cabeçalhos corretos e o conteúdo do arquivo usando o URLRequest via UPLOPLOPOSTHELPER CLASS. Isso funciona 100%, estou usando esta classe para fazer upload de imagens geradas e arquivos CSV, mas você pode fazer upload de qualquer tipo de arquivo.

Esta classe simplesmente prepara a solicitação com cabeçalhos e conteúdo como se você estivesse enviando o arquivo a partir de um formulário HTML.

http://code.google.com/p/as3asclbublib/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);

Não tenho certeza disso, mas você já tentou adicionar nome de usuário: senha@ ao início do seu URL?

"http: // nome de usuário: password@yoursite.com/yourservice.ext"

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();

Problema aparentemente semelhante foi resolvido aqui. Peço que você também verifique o FlexCoders post ligado ao primeiro post.

O problema foi que o Firefox usa uma instância de janela do navegador separada para enviar a solicitação de upload do arquivo. A solução é anexar manualmente o ID da sessão ao URL da solicitação. O ID da sessão não é anexado como uma variável regular, mas com um semicolon (o motivo dessa sintaxe é desconhecido para mim).

O Flash é muito limitado em termos de que tipo de cabeçalhos você pode passar com uma solicitação HTTP (e muda entre navegadores e sistemas operacionais). Se você fizer isso funcionar em um navegador/os, teste -o nos outros.

A melhor coisa a fazer é não mexer com os cabeçalhos HTTP.

Temos o mesmo problema (carregando os álbuns da web do Picasa do Flash) e publicamos por meio de um proxy em nosso servidor. Passamos os cabeçalhos extras como parâmetros pós e nosso proxy faz a coisa certa.

"http: // nome de usuário: password@yoursite.com/yourservice.ext"

Isso não funciona no IE (http://www.theregister.co.uk/2004/01/30/ms_drop_authentication_technique/) e também não parece funcionar no Chrome.

Provavelmente não é utilizável no flash

Aqui é um modo de contornar quando utilizar ASP.Net baseado em parte no trabalho aqui.

Eu construí um componente que dinamicamente escreve Flex objetos para a página, para que eles podem ser usados em UpdatePanels.Pra mim se você deseja que o código.Para resolver o problema acima nas páginas onde os cookies de autenticação precisará ser enviada pelos URLRequest, eu adicionar os valores em como flashVars.

Este código funciona apenas no meu objeto, mas você começa a idéia

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);

Em seguida, no Flex Objeto, verifique se os parâmetros

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 algo que os cookies no 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) { }   

}

Espero que isso ajude alguém a evitar a 6 horas, eu só passei a abordar esta.A Adobe tenha fechado o problema não resolvido, de modo que este foi o meu último recurso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top