Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Relogin & LoginRequiredCallback Session Timeout

    We are trying to catch the callback for the session timeout in SmartGWT by using the LoginRequiredCallback interface. The only issue is that when the user session times out we are not getting the callback method loginRequired(...) called.

    The documentation is minimal on this functionality besides the basic JavaDoc, is there a more concrete example of this function. I have read the ReLogin and LoginRequiredCallback info but no luck.

    Is there another configuration item to make this callback work?

    Thanks in Advance.

    #2
    Whatever response your server returns when the session is expired must contain the loginRequired marker. This is how SmartGWT knows the session is timed out.

    Comment


      #3
      Session Timeout

      Do you have some sample code of this?

      Is this server response via the ServiceImpl or via the Web Server? How do you hook in the loginRequired marker.

      Can you provide some explanation of how the server and client talk to each other to handle session timeout? I really need some documentation and/or example to handle this.

      Thanks again,

      Comment


        #4
        It's simpler than you seem to think. The loginRequiredMarker simply needs to appear in the HTTP response, that's it. This will trigger the relogin flow.

        Here it is for your convenience.

        Code:
        <SCRIPT>//'"]]>>isc_loginRequired
        //
        // Embed this whole script block VERBATIM into your login page to enable
        // SmartClient RPC relogin.
        while (!window.isc && document.domain.indexOf(".") != -1) {
            try {
        	//>IDocument
        	// Safari doesn't throw an exception, but returns null.
        	//<IDocument
                if (parent.isc == null) {
                    document.domain = document.domain.replace(/.*?\./, '');
                    continue;
                } 
                break;
            } catch (e) {
                document.domain = document.domain.replace(/.*?\./, '');
            }
        }
        var isc = top.isc ? top.isc : window.opener ? window.opener.isc : null;
        if (isc) isc.RPCManager.delayCall("handleLoginRequired", [window]);
        </SCRIPT>

        Comment


          #5
          Session Timeout

          Hi There, thanks for the response. We put that in our only Main.html page that is our EntryPoint for all of our GWT pages but unfortunately it did not call our session timeout callback class that implements the LoginRequiredCallback interface.

          The code below is in our Main.java which is our EntryPoint.

          Code:
                  LoginRequiredCallbackImpl loginCallback = new LoginRequiredCallbackImpl();
          
                  RPCManager.setLoginRequiredCallback(loginCallback);
          And the LoginRequiredCallbackImpl has the following:

          Code:
              public class LoginRequiredCallbackImpl implements LoginRequiredCallback {
          
                  public void loginRequired(int transactionNum, RPCRequest request, RPCResponse response) {
                      SC.say("***** SESSION TIMEOUT callback!");
                  }
              }
          Does this require that the server have the SmartGWT EE on the server also? or just use the SmartGwt.jar.

          Thanks for helping again.

          Comment


            #6
            So yet again, what you need to do is put the loginRequiredMarker in the HTTP response that SmartGWT will receive when there is an attempt to load data but the session is timed out. Not in some other random HTML file. In the HTTP response that SmartGWT will receive when there is an attempt to load data but the session is timed out.

            Comment


              #7
              Session Timeout Response

              I have taken your feedback and changed by server side implementation class to check for an expired session and if so then write your JavaScript as stated above into the response.

              The above code does get called at session timeout but unfortunately it still does not work. Please just provide a simple trivial example that demonstrates this functionality if this is wrong.

              Code:
                      if ((SecurityContextHolder.getContext() == null)
                              || (SecurityContextHolder.getContext().getAuthentication() == null)
                              ||!SecurityContextHolder.getContext().getAuthentication().isAuthenticated()
                              || (SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof String)) {
                      	
                          	HttpServletResponse response = this.getThreadLocalResponse();
                          	String scriptText = "<SCRIPT>//'\"]]>>isc_loginRequired "+
              				        "// Embed this whole script block VERBATIM into your login page to enable"+
              				        "// SmartClient RPC relogin."+
              				        " while (!window.isc && document.domain.indexOf(\".\") != -1) {"+
              				        "    try { "+
              				        "	//>IDocument "+
              				        "	// Safari doesn't throw an exception, but returns null."+
              				        "	//<IDocument "+
              				        "        if (parent.isc == null) { "+
              				        "            document.domain = document.domain.replace(/.*?\\./, ''); "+
              				        "            continue; "+
              				        "        } "+ 
              				        "        break; "+
              				        "    } catch (e) { "+
              				        "        document.domain = document.domain.replace(/.*?\\./, ''); "+
              				        "    } "+
              				        " } "+
              				        " var isc = top.isc ? top.isc : window.opener ? window.opener.isc : null; "+
              				        " if (isc) isc.RPCManager.delayCall(\"handleLoginRequired\", [window]); "+
              				        " </SCRIPT> ";
                          	try {
                          		ServletOutputStream stream = response.getOutputStream();
                          		stream.write(scriptText.getBytes());
                          		stream.flush();
                          		stream.close();
                          	} catch (IOException ioe){
                          		log.error("Failed to output script logout text");
                          	}
                          	return null;
                          }

              Comment


                #8
                No need to see the Java code, just use Firebug, Fiddler or any other similar tool to verify that you are sending the response you intend.

                Sorry, we can't keep helping you with this when so many others have it working without assistance. If you need some more help, consider purchasing support. Best of luck.

                Comment


                  #9
                  Session Timeout Response

                  We have looked throughout this forum and found no answers to the LoginRequiredCallback or handling of Session Timeout that are complete. This is a critical piece for web development and is unfortunately missing from this forum. I would sign up for support if I felt that this posting could be answered and sample code provided.

                  Comment


                    #10
                    Then you should sign up for support.

                    Sorry if you're frustrated, please understand, Isomorphic Support is not allowed to spend large amounts of time helping non-paying users to configure something that is known to work, and where others have succeeded. Become a customer and things are different.

                    Comment


                      #11
                      We are having an issue triggering the SmartGWT session timeout...

                      Specifically, we are using Spring which will redirect all unauthenticated requests to a login page, which includes any requests to the RemoteServiceServlet's. So after login, if there is a session timeout the next SmartGWT request to the RemoteServiceServlet will cause the spring framework to redirect to the login page, providing the login page as a response...

                      The login page gets rendered, but usually within a panel of the SmartGWT interface screen. This login page contains the loginRequiredMarker code, but this JavaScript does not seem to get triggered. Infact we have tried embedding out own JavaScripts code into the page (to redirect the parent window), but this JavaScript does not get called. Its as if all JavaScript in disabled in this context? Is there a way to enable it?

                      Comment


                        #12
                        Hi Andrew,

                        How do you end up with your login form showing in a panel somewhere? The normal behavior of SmartGWT's comm system (RPCManager) would not show the login page anywhere. If you are using some other type of comm system (maybe GWT-RPC?) that would explain both the login page appearing and the loginRequiredMarker not working.

                        Comment


                          #13
                          Hi
                          I am using gwt 1.7.0 and smartgwt 1.1
                          I have tried to add to application session timeout functionality.
                          According to relogin described in smartclient documentation, when session becomes invalid my servlet return loginRequiredMarker. It works fine, loginrequired() method is called, I show login dynamicform and in my login servlet new session is created and I call RPCManager.resendTransaction() method. This cause to call again servlet which had session timeout. This time session is valid data is returned and here is my problem: grid which call request does not show any data. In developer console there is no error or warn about something goes wrong.
                          Below developer console log since call to servlet which had session timeout:
                          Code:
                          01:03:23.484:MUP3:INFO:ResultSet:isc_ResultSet_84 (created by: lista):Invalidating cache
                          01:03:23.484:MUP3:DEBUG:ListGrid:lista:Setting filter to: {
                          }
                          01:03:23.484:MUP3:INFO:ResultSet:isc_ResultSet_84 (created by: lista):setCriteria: filter criteria changed, invalidating cache
                          01:03:23.484:MUP3:INFO:ResultSet:isc_ResultSet_84 (created by: lista):Invalidating cache
                          01:03:23.500:MUP3:DEBUG:ResultSet:isc_ResultSet_84 (created by: lista):getRange(0,16), cache check: 5,10 firstMissingRow: 5 lastMissingRow: 10
                          01:03:23.500:MUP3:DEBUG:ResultSet:isc_ResultSet_84 (created by: lista):getRange: no scrolling direction detected
                          01:03:23.500:MUP3:INFO:ResultSet:isc_ResultSet_84 (created by: lista):getRange(0, 16) will fetch from 0 to 16
                          01:03:23.500:MUP3:INFO:ResultSet:isc_ResultSet_84 (created by: lista):fetching rows 0,16 from server
                          01:03:23.515:MUP3:DEBUG:RPCManager:Using ActiveX XMLHttpRequest via constructor: MSXML2.XMLHTTP
                          01:03:23.515:MUP3:DEBUG:RPCManager:Grabbed prompt from first request that defined one: Wyszukiwanie rekordów odpowiadających kryteriom...
                          01:03:23.625:MUP3:INFO:RPCManager:sendQueue[5]: 1 RPCRequest(s); transport: xmlHttpRequest; target: http://localhost:8081/Struktura_springsmartWS/struktura_springsmart/../GetPodmioty.Servlet
                          01:03:23.625:MUP3:DEBUG:RPCManager:Using ActiveX XMLHttpRequest via constructor: MSXML2.XMLHTTP
                          01:03:23.625:MUP3:DEBUG:RPCManager:XMLHttpRequest POST to http://localhost:8081/Struktura_springsmartWS/struktura_springsmart/../GetPodmioty.Servlet contentType: text/xml with body -->
                          <request>
                              <data>
                                  <PodmiotyDS/>
                              </data>
                              <dataSource>PodmiotyDS</dataSource>
                              <operationType>fetch</operationType>
                              <operationId></operationId>
                              <startRow>0</startRow>
                              <endRow>16</endRow>
                              <sortBy></sortBy>
                              <textMatchStyle>exact</textMatchStyle>
                              <componentId>lista</componentId>
                              <oldValues></oldValues>
                          </request><--
                          01:03:23.734:RDQ9:DEBUG:ListGrid:lista:delaying adjustOverflow: childResized
                          01:03:23.734:RDQ9:DEBUG:ResultSet:isc_ResultSet_84 (created by: lista):getRange(0, 16) satisfied from cache
                          01:03:23.765:XRP1:INFO:RPCManager:transaction 5 arrived after 140ms
                          01:03:23.765:XRP1:INFO:RPCManager:loginRequired for transaction: 5
                          01:03:23.906:RDQ2:DEBUG:ResultSet:isc_ResultSet_84 (created by: lista):getRange(0, 16) satisfied from cache
                          01:04:22.750:MUP2:DEBUG:RPCManager:Using ActiveX XMLHttpRequest via constructor: MSXML2.XMLHTTP
                          01:04:22.828:MUP2:INFO:RPCManager:sendQueue[6]: 1 RPCRequest(s); transport: xmlHttpRequest; target: http://localhost:8081/Struktura_springsmartWS/struktura_springsmart/../CheckUser.Servlet
                          01:04:22.828:MUP2:DEBUG:RPCManager:Using ActiveX XMLHttpRequest via constructor: MSXML2.XMLHTTP
                          01:04:22.828:MUP2:DEBUG:RPCManager:XMLHttpRequest POST to http://localhost:8081/Struktura_springsmartWS/struktura_springsmart/../CheckUser.Servlet contentType: text/xml with body -->
                          <DSUser>
                              <login>a</login>
                              <passwd>a</passwd>
                          </DSUser><--
                          01:04:22.875:XRP8:INFO:RPCManager:transaction 6 arrived after 47ms
                          01:04:22.875:XRP8:DEBUG:RPCManager:Result string for transaction 6: "<?xml version="1.0" encoding="UTF-8"?>
                          <users>
                            <user>
                              <login>a</login>
                              <passwd>a</passwd>
                              <opis>Szybki user</opis>
                              <logCheck>checked</logCheck>
                            </user>
                          </users>
                          
                          "
                          01:04:22.890:XRP8:INFO:RPCManager:rpcResponse(unstructured) results -->"<?xml version="1.0" encoding="UTF-8"?>
                          <users>
                            <user>
                              <login>a</login>
                              <passwd>a</passwd>
                              <opis>Szybki user</opis>
                              <logCheck>checked</logCheck>
                            </user>
                          </users>
                          
                          "<--
                          01:04:22.968:XRP8:DEBUG:ListGrid:lista:delaying adjustOverflow: childClear
                          01:04:23.109:XRP8:DEBUG:ResultSet:isc_ResultSet_84 (created by: lista):getRange(0, 16) satisfied from cache
                          01:04:23.484:XRP8:INFO:RPCManager:Resubmitting transaction number: 5
                          01:04:23.484:XRP8:INFO:RPCManager:sendQueue[5]: 1 RPCRequest(s); transport: xmlHttpRequest; target: http://localhost:8081/Struktura_springsmartWS/struktura_springsmart/../GetPodmioty.Servlet
                          01:04:23.484:XRP8:DEBUG:RPCManager:Using ActiveX XMLHttpRequest via constructor: MSXML2.XMLHTTP
                          01:04:23.500:XRP8:DEBUG:RPCManager:XMLHttpRequest POST to http://localhost:8081/Struktura_springsmartWS/struktura_springsmart/../GetPodmioty.Servlet contentType: text/xml with body -->
                          <request>
                              <data>
                                  <PodmiotyDS/>
                              </data>
                              <dataSource>PodmiotyDS</dataSource>
                              <operationType>fetch</operationType>
                              <operationId></operationId>
                              <startRow>0</startRow>
                              <endRow>16</endRow>
                              <sortBy></sortBy>
                              <textMatchStyle>exact</textMatchStyle>
                              <componentId>lista</componentId>
                              <oldValues></oldValues>
                          </request><--
                          01:04:23.812:XRP8[E]:WARN:DynamicForm:isc_OID_20:couldn't find focus item: undefined
                          01:04:24.468:XRP8[E]:DEBUG:ListGrid:lista:delaying adjustOverflow: childResized
                          01:04:24.484:XRP8[E]:DEBUG:ListGrid:isc_OID_47:delaying adjustOverflow: childResized
                          01:04:24.625:XRP0:INFO:RPCManager:transaction 5 arrived after 1141ms
                          01:04:24.625:XRP0:DEBUG:RPCManager:Result string for transaction 5: "<?xml version="1.0" encoding="UTF-8"?>
                          <response>
                            <status>0</status>
                            <startRow>0</startRow>
                            <endRow>16</endRow>
                            <totalRows>350</totalRows>
                            <data>
                              <record>
                                <idPodm>3</idPodm>
                                <imie>Dodany podmiot</imie>
                                <nazwisko>Jakiś tam podmiot nr: 3</nazwisko>
                                <dodane>2009-07-15 11:25:11.524</dodane>
                              </record>
                          ...
                             </data>
                          </response>
                          
                          "
                          01:04:24.656:XRP0:INFO:RPCManager:rpcResponse(unstructured) results -->"<?xml version="1.0" encoding="UTF-8"?>
                          <response>
                            <status>0</status>
                            <startRow>0</startRow>
                            <endRow>16</endRow>
                            <totalRows>350</totalRows>
                            <data>
                              <record>
                                <idPodm>3</idPodm>
                                <imie>Dodany podmiot</imie>
                                <nazwisko>Jakiś tam podmiot nr: 3</nazwisko>
                                <dodane>2009-07-15 11:25:11.524</dodane>
                              </record>
                          ...
                            </data>
                          </response>
                          
                          "<--
                          01:04:24.734:XRP0:INFO:ResultSet:isc_ResultSet_84 (created by: lista):Received 16 records from server
                          01:04:24.765:XRP0:DEBUG:ResultSet:isc_ResultSet_84 (created by: lista):full length set to: 350
                          01:04:24.781:XRP0:DEBUG:ResultSet:isc_ResultSet_84 (created by: lista):integrating 16 rows into cache at position 0
                          01:04:24.796:XRP0:INFO:ResultSet:isc_ResultSet_84 (created by: lista):cached 16 rows, from 0 to 16 (350 total rows, 16 cached)
                          Am I missing something ?

                          Comment


                            #14
                            That log looks fine. Goods things to look at:

                            1. what component is clear()ing here? Try the clear()s log in the Developer Console

                            01:04:22.968:XRP8:DEBUG:ListGrid:lista:delaying adjustOverflow: childClear

                            2. try inspecting the state of the ResultSet after the transaction has resubmitted and completed, eg, what's grid.data.get(0) and does lengthIsKnown() return true. You can do this by writing JavaScript in the Developer Console in SmartGWT 1.1, or since there are now ResultSet APIs in SmartGWT 1.2, you can upgrade and write code that logs the results of calling various methods.
                            Last edited by Isomorphic; 10 Aug 2009, 15:39.

                            Comment


                              #15
                              Originally posted by Isomorphic
                              Hi Andrew,

                              How do you end up with your login form showing in a panel somewhere? The normal behavior of SmartGWT's comm system (RPCManager) would not show the login page anywhere. If you are using some other type of comm system (maybe GWT-RPC?) that would explain both the login page appearing and the loginRequiredMarker not working.
                              Thanks for the help. Although, where can I check to verify if the RPCManager is being used? It seems other callback functions registered by the RPCManager are also not working, so I think you may be right. Where are the setting(s) to change the comm manager being used so I can set it to the RPCManager?

                              Comment

                              Working...
                              X