History | Log In     View a printable version of the current page.  
Issue Details (XML)

Key: BLZ-64
Type: Bug Bug
Status: Open Open
Priority: C C
Assignee: peterson
Reporter: Tyson Norris
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
BlazeDS

LoginCommand.logout() not called when executing RemoteObject.logout()

Created: 02/21/08 02:02 PM   Updated: 05/15/08 05:49 PM
Component/s: RemoteObject
Security Level: Public (All JIRA Users )

Severity: Conflicts with Docs
Reproducibility: Every Time
Discoverability: Medium
Found in Version: BlazeDS 3.0.0
Milestone: BlazeDS 3.0.2
Affected OS(s): Windows - XP
Steps to Reproduce:
Steps to reproduce:
1. create a custom login adapter (implementation of LoginCommand) (we are using Resin app server, not sure if that matters)
2. create RemoteObject, use setCredentials to authenticate session (note that LoginCommamd.doAuthentication() and LoginCommand.doAuthorization()) are properly executed
3. create RemoteObject and invoke logout():
var ro:RemoteObject = new RemoteObject();
ro.destination = "LoginService";
ro.addEventListener("result", onLogoutSuccess);
ro.addEventListener("fault", onFault);
ro.logout();
 
 Actual Results:
 nothing - no indication that any message is sent to server; no execution of result or fault event handler
 
 Expected Results:
 LoginCommand.logout() should be executed
 
 Workaround (if any):
 none that I know of; We need a way to allow the user to terminate the FlexSession instance, preferably using the LoginCommand.logout() API.
 
 
Language Found: English
Bugbase Id: none
Triaged: Yes
Regression: No
QA Owner: wichan
Participants: Mete Atamel, peterson, Trevor Baker and Tyson Norris
Browser: Firefox 2.x
JDK: Sun JDK 5


 All   Comments      Sort Order:
Mete Atamel - [03/18/08 12:39 PM ]
I tested this scenario with Tomcat's LoginCommand implementation and it works as expected. On the client, I call remoteObject.logout() and I see the following in debug logs on the server which tells me that the server gets the logout command message:

[BlazeDS] [DEBUG] [Message.Command.logout] Executed command: service=authenticat
ion-service
  commandMessage: Flex Message (flex.messaging.messages.CommandMessage)
    operation = logout
    clientId = 73EA16CE-4E0A-A11B-5566-00DF8ABEFC28
    correlationId =
    destination =
    messageId = B2368423-BFAC-7CE5-D8E8-C2EF3DFF664F
    timestamp = 1205861301806
    timeToLive = 0
    body = {}
    hdr(DSEndpoint) = my-amf
    hdr(DSId) = 73E9FEA8-AA0F-4CDF-21EE-71AA71AA9491
  replyMessage: Flex Message (flex.messaging.messages.AcknowledgeMessage)
    clientId = 73EA16CE-4E0A-A11B-5566-00DF8ABEFC28
    correlationId = B2368423-BFAC-7CE5-D8E8-C2EF3DFF664F
    destination = null
    messageId = 73EA16F5-5E0A-841A-476B-4D23CA679A4F
    timestamp = 1205861301822
    timeToLive = 0
    body = success

On the server, I put a breakpoint in LoginManager.logout and TomcatLoginCommand.logout and both methods got hit respectively. So logout is definitely sent from the client to the server and server definitely processes that logout command.

The only thing I can think of is that maybe customer's LoginCommand implementation is not doing something right? So I need more information from the customer for their use case.

Mete Atamel - [03/18/08 12:40 PM ]
Assigning to customer for more information on their use case. Specifically, need more information on their LoginCommand implementation.

Tyson Norris - [05/13/08 11:26 AM ]
When I changed:
var ro:RemoteObject = new RemoteObject();
ro.destination = "ILoginService";
ro.logout();

to:
var ro:RemoteObject = new RemoteObject();
ro.destination = "ILoginService";
if (ro.channelSet == null){
          ro.channelSet = ServerConfig.getChannelSet(ro.destination);
}
var token:AsyncToken = ro.channelSet.logout();
token.addResponder(new AsyncResponder(
    onLogoutSuccess,
    onLogoutFault
));

Then the LoginCommand.logout() method was invoked as desired.

My LoginCommand implementation is very basic (listed below), but the logout() method was NOT invoked when calling it on a RemoteObject using the above code; After changing to ChannelSet.logout(), it is properly invoked.
Thanks
Tyson

public class LoginCommand implements flex.messaging.security.LoginCommand {
  private static final Log log = LogFactory.getLog(LoginCommand.class);
  private static IAccessManager accessManager = null;
  /**
   * @see http://livedocs.adobe.com/livecycle/es/sdkHelp/programmer/lcdsjavadoc/flex/messaging/security/LoginCommand.html#doAuthentication(java.lang.String,%20java.lang.Object)
   */
  public Principal doAuthentication(String username, Object credentials) {
    String password = (String)credentials;
    Principal principal = accessManager.doAuthenticate(username, password);
    if( principal != null ) {
        FlexContext.setUserPrincipal(principal);
    }
    log.info("authenticating user:" + username);
    return principal;
    //return new MLPrincipal(username);
  }

  public boolean doAuthorization(Principal principal, List roles) {
    log.info("AUTHORIZING user:" + principal.getName());
    //need a way to authorize a particular method that is currently being requested?
    //this method typically operates on a per-service granularity, so all operations hosted by a particular
    //destination have the same authorization rules.
    return true;
  }

  public boolean logout(Principal principal) {
    log.info("logging out user:" + principal.getName());
    
    return true;
  }

  public void start(ServletConfig servletConfig) {
    // TODO Auto-generated method stub
    log.info("starting LoginCommand...");
  }

  public void stop() {
    // TODO Auto-generated method stub

  }
  public class MLPrincipal implements Principal{
    private String name;
    public MLPrincipal(String name){
      this.name = name;
    }
    public String getName() {
      return name;
    }
    
  }
    
    public static void setAccessManager(IAccessManager accessMgr) {
        accessManager = accessMgr;
    }
}

Mete Atamel - [05/15/08 11:00 AM ]
This is the expected "legacy" behavior of RemoteObject.logout. ChannelSet.login/logout is the right way of authenticating and when you use RemoteObject.logout, it eventually goes to ChannelSet.logout according to the ASDoc comment from ChannelSet class:

     * Legacy behavior only sends a logout request to the server if the client is connected
     * and authenticated.
     * If these conditions are not met the legacy behavior for this method is to do nothing other
     * than clear any credentials that have been cached for use in automatic reconnects.

In this case, that particular RemoteObject instance was not connected, so calling RemoteObject.logout would not do anything.

However, we need to update ASDocs for RemoteObject, Producer, Consumer, etc. to indicate that ChannelSet.login/logout() is the preferred way now.


Mete Atamel - [05/15/08 11:01 AM ]
Changing severity to "Conflicts with Documentation"

Trevor Baker - [05/15/08 03:09 PM ]
doc issue