Handling Client-Side Authentication (DA/.NET)

This is an Article about Data Abstract for .NET
(This page is considered "good" on a technical level, but is pending review for grammar and typos)
Overview
It is not possible to access services that have RequireSession set to true (called protected below) without authenticating on the server first. The server application will respond with the SessionNotFoundException exception on all attempts to access protected services by non-authenticated clients. This article describes how authentication should be performed by the Data Abstract for .NET client application.
At the same moment there is no need to change any methods that actually access protected service's methods. All necessary checks will be transparently performed by the RemObjects SDK framework, so there are no code or workflow differencies between accessing protected and unprotected services given that user has authenticated successfully.
Note: Please refer to this article to find how to enable authentication in a Data Abstract for .NET server application.
Authentication is performed via calling the server's Login or LoginEx method. This method can be called explicitly at application startup or in the client channel's OnLoginNeeded event handler.
Obviously former approach is more preferred because
- Login Service call might require user to input user id and password, so it is better to request user's credentials at application startup than on random moment during application run
- Login Service call can take considerable time, so from UX side the user will be more aware what exactly the application does
Authentication
Login method call doesn't differ from any RemObjects SDK service:
- Create remote service proxy
- Call the method
- Check the result
Is strongly suggested to implement Login Service as descendant of the SimpleLoginService service predefined in the Data Abstract for .NET. This gives a major benefit: there is no need to import the service's RODL and generate any custom interface (_Intf) files to be able to access service's methods. Also LoginEx implemented as main server's login interface makes it extensible and consistent at the same time.
The code to call the login method is rather simple:
(new RemObjects.DataAbstract.Server.BaseLoginService_Proxy(message, clientChannel, "LoginService")) .LoginEx("User=UserName;Password=UserPassword");
The LoginEx method returns true if the server accepted provided credentials and login was successful. Despite its namespace the RemObjects.DataAbstract.Server.BaseLoginService_Proxy class is defined in the RemObjects.DataAbstract.dll assembly and is available on all platforms supported by the Data Abstract for .NET
Default implementation of the OnLoginEvent event handler is simple as well, yet requires some more code:
private void ClientChannel_OnLoginNeeded(object sender, LoginNeededEventArgs e) { // Performing login if (this.LogOn(this.UserId, this.Password)) { e.Retry = true; e.LoginSuccessful = true; return; } // Show dialog to let user provide username and password String lUserId; String lPassword; using (LogOnForm loginForm = new LogOnForm()) { if (loginForm.ShowDialog() != DialogResult.OK) { MessageBox.Show("Login cancelled"); return; } lUserId = loginForm.UserId; lPassword = loginForm.Password; } if (this.LogOn(lUserId, lPassword)) { e.Retry = true; e.LoginSuccessful = true; } else { MessageBox.Show("Login failed"); } }
Note the assignments
e.Retry = true; e.LoginSuccessful = true;
The first assignment notifies the client channel instance that raised the event that it should ignore the SessionNotFound exception and attempt to access the data again. The second one notifies the client channel that the user has authenticated successfully. Obviously just setting this parameter to true without performing successful authentication first won't allow authenticated user to access the protected services.
Also this code shows the main disadvantage of using OnLoginEvent event handler to perform initial authentication: it requires some way to acquire user credentials. This would cause unnecessary code complexity in applications where layered design is used where data access layer that access remote servers is separated from the GUI layer.
Summary
From the Data Abstract for .NET point of view adding authentication to the client application is a rather simple task that requires no more than 1 service method call.
See Also
Product Articles — Data Abstract — RemObjects SDK — Hydra

Product: RemObjects Data Abstract
Available Editions: Data Abstract for .NET, Xcode, Delphi, Java and JavaScript