Skip to main content
Participant
March 5, 2008
Question

How to *reset* credentials with Consumer?

  • March 5, 2008
  • 11 replies
  • 29724 views
Hi,

I've been trying authentication on BlazeDS and Tomcat using "flex.messaging.security.TomcatValve".

I succeeded authentication only *once*.

I thought things goes like this,
-----
1. Consumer#setCredentials("user1", "pass1")
2. Do something.
3. Consumer#logout()
4. Consumer#setCredentials("user2", "pass2") // Relogin as different user.
5...
-----

But at "4", error occured bellow
-----
Error: Credentials cannot be set while authenticating or logging out.
at mx.messaging::Channel/setCredentials()
at mx.messaging::ChannelSet/setCredentials()
at mx.messaging::MessageAgent/setCredentials()
-----

Then I tried *without* calling Consumer#logout(), other error occured.
-----
Error: Credentials cannot be set when already authenticated. Logout must be performed before changing credentials.
at mx.messaging::Channel/setCredentials()
at mx.messaging::ChannelSet/setCredentials()
at mx.messaging::MessageAgent/setCredentials()
-----

It's completely opposite.
So how should I do?
I'm not good at Enlish but hope make sense.

Thank you.
    This topic has been closed for replies.

    11 replies

    Participant
    May 4, 2008
    In fact, there is no need to wait any connected event. So the following code works.

    if(service.channelSet == null) {
    service.channelSet = ServerConfig.getChannelSet(this.destinationId);
    }
    var token:AsyncToken = service.channelSet.login(this.currentUser.name, this.currentUser.password);
    Participant
    May 4, 2008
    In my application, channelConnected is never called.

    Could it be possible that there is some kind of lazy connection ?
    If someone could post the source code of the whole class, it could be really usefull for me.

    A significant difference is that I don' use consumer, but directly a RemoteObject.
    Participant
    March 18, 2008
    Mete, your recomendation worked. I've added your two lines to my onComplete event handler of my application to initialize. And I no longer get the null object error.
    Does it mean that, adding the <mx:RemoteObject> doesn't initialize the channelSet that your destination is defaulted to use. Anyways, thanks again.
    Participant
    March 17, 2008
    Not to repeat what was said immediately above... :)

    I've run into related issues. You can add an event listener for when the channel connects, so you won't end up invoking methods or looking for properties on a null object.

    private var cs:ChannelSet;
    cs = mx.messaging.config.ServerConfig.getChannelSet("userService");
    cs.addEventListener(mx.messaging.events.ChannelEvent.CONNECT, channelConnected);

    where userService is my destination id, and channelConnected is the function where I start calling methods on the channelSet.
    March 17, 2008
    First, can you provide us a simple repro case that shows the behavior? (to make sure it is not a bug).

    Second, consumer.channelSet can be null if consumer is not connected yet but you can also "force" channelSet to be initialized with:

    var destinationId:String = ""; // Set it to the destination id
    consumer.channelSet = ServerConfig.getChannelSet(destinationId);

    // Now, consumer.channelSet should not be null.
    Participant
    March 17, 2008
    consumer.channelSet.login call fails for me since consumer.channelSet is null. Other than defining your remote object, is there anything required to initialize the channelSet or something. Puzzled.
    Participant
    March 14, 2008
    Hello everyone!
    Thanks lots, I've just changed to use ChannelSet methods.
    And show my code bellow.

    // When login.
    var token:AsyncToken = consumer.channelSet.login(username.text, password.text);
    token.addResponder(new AsyncResponder(
    function(re:ResultEvent, token:Object=null):void {
    switch (re.result) {
    case "success":
    consumer.addEventListener(MessageFaultEvent.FAULT, handleMessageFault);
    consumer.addEventListener(MessageAckEvent.ACKNOWLEDGE, checkAuthentication);
    consumer.subscribe();
    break;
    default:
    trace(re);
    trace(token);
    }
    },
    function(fe:FaultEvent, token:Object=null):void {
    switch (fe.fault.faultCode) {
    case "Client.Error.MessageSend":
    information.text = "Failed to connect.";
    break;
    case "Client.Authentication":
    information.text = "Invalid User Name or Password.";
    break;
    default:
    trace(fe);
    trace(token);
    }
    }
    ));

    // When logout.
    consumer.unsubscribe();

    var token:AsyncToken = consumer.channelSet.logout();
    token.addResponder(new AsyncResponder(
    function(re:ResultEvent, token:Object=null):void {
    trace(re);
    },
    function(fe:FaultEvent, token:Object=null):void {
    trace(fe);
    }
    ));

    I hope my code helps you.
    Participating Frequently
    March 13, 2008
    A better approach to handling authentication in BlazeDS is to use the new login() and logout() methods on ChannelSet. These let you cleanly handle any authentication or logout issues, and return a token that you can add a responder to for targeted event handling.

    The old setCredentials() method dates back to Flex 1 and is awkard to use because it may or may not be lazy depending on when you call it and when a connection to the server is actually established, and any authentication problems come back as a fault for an unrelated operation that you've invoked. Similarly, the old logout() method on things like Consumer and RemoteObject doesn't provide a direct way to handle success/fault.

    You should really prefer the use of the new APIs on ChannelSet.

    Best,
    Seth
    Participant
    March 13, 2008
    Daniel, do you have a working code you can post including the remote object definition. When I try the disconnect and call the setcredentials later, I get a null object reference error.
    Participant
    March 11, 2008
    Hi, I had the same problem. The approach I took (which is probably a dirty hack) is to call disconnect() on the RemoteObject before I reset the credentials