public interface Relogin
The ideal handling of this scenario is that the form's attempt to save is "suspended" while the user re-authenticates, then is completed normally. Smart GWT makes it easy to implement this ideal handling without having to implement session timeout handling in every codepath that contacts the server, by providing central notification of session timeout, and the ability to re-send a transaction that encountered session timeout.
To enable Smart GWT to detect that session timeout has occurred, a special marker needs to
be added to the HTTP response that is sent when a user's session has timed out. This is
called the loginRequiredMarker
.
If your authentication system will redirect to a login page when a user's session is timed
out, it's sufficient to simply embed the loginRequiredMarker
in the login page.
The
loginRequiredMarker
is valid HTML and will have no effect on the behavior or
appearance of the page. The loginRequiredMarker
is found in
docs/loginRequiredMarker.html
in your SDK. Simply copy the contents of this file verbatim into your login page anywhere
inside the <body> tag; it does not need to be customized in any way for your application.
The HTML snippet in loginRequiredMarker.html consists of two parts:
loginRequiredMarker
. Responses to standard
xmlHttpRequest transport
RPC requests
will be scanned for this marker
and kick off the loginRequired flow
automatically.hiddenFrame transport
request,
it also includes some
JavaScript to explicitly notify the RPCManager in the Smart GWT app running in the
parent frame or opener window that login is required.
If it's a problem to modify the login page (even with a marker that has no effect on
appearance or behavior), see if you can configure your authentication system to return a
special response specifically for background requests for data. By default, when using the
Smart GWT Server Framework, all such requests go to the actionURL
and
include an HTTP query parameter "isc_rpc=1"; various authentication systems can be
configured to detect these requests and handle them separately. One approach is to simply
copy loginRequiredMarker.html into your application in an area not protected by
authentication and redirect to it when a background data request with an expired session is
detected.
When Smart GWT detects the loginRequiredMarker
, the transaction that
encountered session timeout is put on hold, and
the RPCManager LoginRequired event is raised.
At this point you have a few options:
window.location.replace(myLoginURL)
, the simplest but least user friendly
option.
RPCManager.resendTransaction()
when the user indicates he has logged in.
This is simple, does not drop context, but is not seamless.
RPCManager.resendTransaction()
.
To relogin against any system that can accept credentials as an HTTP POST:
LoginWindow
component is a simple version
of this, or you can create your own
RPCRequest request = new RPCRequest(); request.setContainsCredentials(true); request.setActionURL(credentialsURL); request.setUseSimpleHttp(true); request.setShowPrompt(false); Mapparams = new HashMap (); // adjust parameter names to match your authentication system params.put("j_username",username); params.put("j_password",password); request.setParams(params); RPCManager.sendRequest(request,new RPCCallback(){ public void execute(RPCResponse response, Object rawData, RPCRequest request) { if (response.getStatus() == RPCResponse.STATUS_SUCCESS) { // get rid of login window RPCManager.resendTransaction(); } else if (response.getStatus() == RPCResponse.STATUS_LOGIN_INCORRECT) { // show an error in the login window } } });
loginSuccessMarker
file itself as a
protected resource. The loginSuccessMarker
is found in
docs/loginSuccessMarker.html
in your SDK.
Authentication via background Smart GWT server RPC/DMI
If you are using the Smart GWT Java server and your authentication system allows you to mark a user as authenticated from Java, you can perform a normal RPC or DMI with the credentials gathered from the user and send back success or failure indications as normal RPC or DMI responses. This can be useful if, in addition to logging in, you want to send back additional data.
Advanced: concurrency
If, after loginRequired() has fired and before the user has re-authenticated, you send
additional RPCs to protected URLs, you will get additional loginRequired() notifications. This
may happen to applications that poll for data or periodically save without user action. You
may wish to avoid this by setting an application-specific flag to avoid firing requests during
the relogin process. However, you must ultimately either
resend
or discard
every transaction for which loginRequired() fires, or you will have a memory leak due to
suspended transactions.
Note also that there is no requirement that the relogin process blocks user interaction. Applications that access multiple services may choose to simply show an unobtrusive error indication such that the user can log back in at his leisure, or even log the user back in automatically.
com.smartgwt.client.rpc.RPCManager#loginRequired
,
com.smartgwt.client.rpc.RPCManager#credentialsURL
,
com.smartgwt.client.rpc.RPCManager#loginStatusCodeMarker
,
com.smartgwt.client.rpc.RPCManager#loginRequiredMarker
,
com.smartgwt.client.rpc.RPCManager#loginSuccessMarker
,
com.smartgwt.client.rpc.RPCManager#maxLoginAttemptsExceededMarker
,
com.smartgwt.client.rpc.RPCManager#reloginCommFailureMessage
,
RPCRequest.getContainsCredentials()