Skip navigation
Currently Being Moderated

How to *reset* credentials with Consumer?

Mar 5, 2008 8:33 AM

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.
 
Replies
  • Currently Being Moderated
    Mar 10, 2008 7:45 AM   in reply to (Yoshiyuki_MIKAMI)
    Hi Yoshiyuki,

    You are calling Consumer.setCredentials("user2", "pass2") before Consumer.logout successfully completes. The real problem is though there is no way to know when Consumer.logout has completed. (Consumer.logout is legacy code and it does not work that well.)

    I suggest you use ChannelSet.logout instead. ChannelSet.logout returns an AsyncToken that you can attach result and fault responders to. When ChannelSet.logout returns successfully, you can call Consumer.setCredentials from the result responder.

    I haven't compiled this but it should be something like this:

    var token:AsyncToken = consumer.channelSet.logout();
    token.addResponders(new AsyncResponder(
    function (result:Object, token:Object=null):void
    {
    consumer.setCredentials("user2","pass2")
    },
    function (error:Object, token:Object=null):void
    {
    // Error handling here.
    }));
     
    |
    Mark as:
  • Currently Being Moderated
    Mar 11, 2008 9:08 AM   in reply to (Yoshiyuki_MIKAMI)
    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
     
    |
    Mark as:
  • Currently Being Moderated
    Mar 13, 2008 8:06 AM   in reply to (Yoshiyuki_MIKAMI)
    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.
     
    |
    Mark as:
  • Currently Being Moderated
    Mar 13, 2008 2:34 PM   in reply to (Yoshiyuki_MIKAMI)
    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
     
    |
    Mark as:
  • Currently Being Moderated
    Mar 17, 2008 1:15 PM   in reply to (Yoshiyuki_MIKAMI)
    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.
     
    |
    Mark as:
  • Currently Being Moderated
    Mar 17, 2008 1:36 PM   in reply to (Yoshiyuki_MIKAMI)
    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.
     
    |
    Mark as:
  • Currently Being Moderated
    Mar 17, 2008 2:51 PM   in reply to (Yoshiyuki_MIKAMI)
    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.
     
    |
    Mark as:
  • Currently Being Moderated
    Mar 18, 2008 8:55 AM   in reply to (Yoshiyuki_MIKAMI)
    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.
     
    |
    Mark as:
  • Currently Being Moderated
    May 4, 2008 11:58 AM   in reply to (Yoshiyuki_MIKAMI)
    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.
     
    |
    Mark as:
  • Currently Being Moderated
    May 4, 2008 1:06 PM   in reply to (Yoshiyuki_MIKAMI)
    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);
     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)