Question

J'essaie de demander une ressource HTTP nécessitant des en-têtes d'autorisation de base à partir d'une application Adobe AIR. J'ai essayé d'ajouter manuellement les en-têtes à la requête et d'utiliser la méthode setRemoteCredentials () pour les définir, mais en vain.

Voici le code:

<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" />

Cependant, une boîte de dialogue standard d'authentification de base apparaît toujours, invitant l'utilisateur à entrer son nom d'utilisateur et son mot de passe. J'ai l'impression que je ne le fais pas correctement, mais toutes les informations que j'ai pu trouver (documents Flex, blogs, Google, etc.) n'ont pas fonctionné ou étaient trop vagues pour vous aider.

Une magie noire, oh gourous Flex? Merci.

EDIT: La modification de setRemoteCredentials () en setCredentials () génère l'erreur ActionScript suivante:

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

MODIFIER: Le problème a été résolu, après un peu d'attention d'Adobe. Voir les messages ci-dessous pour une explication complète. Ce code fonctionnera pour les en-têtes d’authentification HTTP de longueur arbitraire.

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();
}
Était-ce utile?

La solution

Enfin, Adobe a attiré l'attention et obtenu une réponse à ce sujet. Le problème avec les en-têtes d'authentification HTTP longs est que, par défaut, la classe Base64Encoder injectera des caractères de nouvelle ligne tous les 72 caractères. Évidemment, cela provoque l'interprétation d'une partie de la chaîne codée en base 64 comme un nouvel attribut d'en-tête, ce qui entraîne l'erreur.

Vous pouvez résoudre ce problème en définissant (dans l'exemple ci-dessus) encoder.insertNewLines = false; Le paramètre par défaut est true.

J'ai corrigé le code ci-dessus pour qu'il fonctionne avec des chaînes d'authentification arbitrairement longues.

Autres conseils

Ah. La douleur, la souffrance La pure misère.

Bien que vous ayez compris comment ajouter un en-tête avant de passer votre appel, la triste vérité est que, quelque part au fond de l'espace d'intégration Flash / navigateur, vos en-têtes sont à nouveau supprimés.

De mon article de blog de l'année dernière sur verveguy.blogspot.com

J'ai donc dévoilé la vérité. (Je pense) Il est plus torturé qu'on pourrait l'imaginer

1 / Toutes les demandes HTTP GET sont dépourvues d'en-têtes. Ce n’est pas dans la pile Flex, c’est donc probablement le moteur d’exécution sous-jacent de Flash Player

2 / Toutes les requêtes HTTP GET dont le type de contenu est autre que application/x-www-form-urlencoded sont transformées en requêtes POST

.

3 / Toutes les requêtes HTTP POST ne contenant aucune donnée validée sont converties en requêtes GET. Voir 1 / et 2 /

4 / Toutes les requêtes HTTP PUT et HTTP DELETE sont transformées en requêtes POST. Cela semble être une limitation du navigateur qui bloque le lecteur Flash. (?)

En gros, cela revient à dire que si vous voulez passer des en-têtes dans toutes les demandes, vous devez toujours utiliser POST et trouver un autre moyen de communiquer la sémantique de l'opération que vous & avez vraiment souhaitée < !> quot. La communauté Rails a décidé de passer ?_method=PUT/DELETE comme solution de contournement aux problèmes de navigateur sous-jacents 4 /

.

Depuis que Flash ajoute l’entête merveilleuse qui soulage la douleur sur GET, j’utilise aussi ?_method=GET pour contourner ce problème. Cependant, puisque cela déclenche le 3 /, Je passe un objet factice en tant que données POST codées. Ce qui signifie que mon service doit ignorer les données factices publiées sur une <=> demande.

Crucial à ce stade de savoir sur 2 /. Cela m'a fait perdre beaucoup de temps.

J'ai intégré toute cette gestion dans une nouvelle classe RESTService avec prise en charge du balisage MXML, de sorte qu'il est possible de prétendre que cela n'existe pas côté client.

J'espère que cela aide quelqu'un.

Le setCredentials () & amp; Les méthodes setRemoteCredentials () sont destinées à être utilisées avec Flex / LiveCycle Data Services. Elles ne sont donc probablement pas applicables dans votre cas.

Cela devrait fonctionner pour vous. J'ai pu reproduire ce problème sur mon serveur et ce correctif semble avoir fait l'affaire; cela semble toujours un peu bizarre, ce n’est pas plus convivial avec les API, si l’on pense à un cas d’utilisation courant, mais j’ai néanmoins testé et vérifié que cela fonctionne, avec un certificat SSL valide:

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

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

J'espère que ça aide! Et merci d'avoir posté - je suis sûr que je l'aurais rencontré tôt ou tard moi-même. ;)

Cela m’a vraiment aidé! Merci! J'utilise Flex Builder 3

Remarque: les en-têtes de propriété de WebService sont en lecture seule. J'ai donc essayé d'utiliser httpHeaders. Ça marche!

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

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

J'ai eu le même problème lors de l'utilisation du service Web d'authentification de base HTTP. C'est ma solution. ça marche 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();
}

utilisation

authAndSend(WebService( aWebServiceWrapper.serviceControl));

Essayez d'utiliser setCredentials plutôt que setRemoteCredentials, sinon utilisez Fiddler / Charles pour savoir quels en-têtes sont envoyés avec la requête.

Par ailleurs, afin que les autres personnes ne passent pas 10 minutes à comprendre pourquoi le Le bon exemple ne fonctionne pas très bien en tant que tel, vous devez importer le package mx.utils.Base64Encoder, par exemple:

        import mx.utils.Base64Encoder;

Au début ou quelque part dans la zone CDATA. Je suis nouveau en flexion, donc ce n’était pas évident au début.

Voici comment cela se fait.

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()}; 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top