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);
Map params = 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()