LoginEx
Overview
In some cases, a server application requires the user to provide more information than just a username and password to perform the login action. Relativity Server, for example, also requires a Domain
name or a User Access Level
descriptor.
Of course it is possible to add several Login method overloads with different parameters accepted, but this approach has several major caveats:
- The developer will have to keep in sync the
_Intf
file used in the client application(s) and the server RODL. - There could be dozens of possible login parameter combinations, so it will be difficult to cover them all with login service method definitions.
- Code implementing the Login Service will soon bloat and become a mess with spaghetti-like code.
Resolving this problem was the main reason for introducing the LoginEx feature. It provides a clean and reliable solution for all of the above-mentioned caveats:
- Single entry-point method
- No need to import the server application RODL
- All possible login parameter combinations can be covered by a single API method
LoginEx in details
Rather than passing individual parameters, LoginEx provides a common Login service interface based on the connection string approach that can, in addition to username and password, provide an arbitrary number of parameters required by the server. For example, Relativity Server has a Domain
parameter and (optionally) a Schema
parameter.
The format of the connection string is quite straightforward – several key-value pairs separated by a ; symbol, for example
User Id=Data;Password=Relativity;Domain=PCrade Sample;Schema=PCTrade
This LoginEx string
(or login string
) defines a connection with username Data and password Relativity, as well as two additional login parameters, Domain
and Schema
.
The default implementation of the LoginEx method extracts the username and password from the provided connection string and passes them to the Login method. The service implementation method LoginEx(String)
should be overridden in case more advanced implementation is needed.
LoginEx connection string parser
Data Abstract provides built-in LoginEx connection string parser classes: LoginStringParser for .NET and TLoginString for Delphi.
Escaping special symbols
To use a semicolon (;
) in a connection string entry name or value, the entire value should be surrounded by quotes (”
).
Custom Entry="Custom Entry=Inner Value;Something=Alpha""Value";"Custom Entry 2"=Some Value"" Here;
This connection string defines two key-value pairs:
- Key Custom Entry, value Custom Entry=Inner Value;Something=Alpha"Value"
- Key Custom Entry 2, value Some Value" Here
Note how the "
symbol was escaped in the above key-value pairs.
Composing LoginEx method
At the first glance the login string van be composed using simple string concatenation:
var loginString = "User ID=" + userName + ";Password=" + password;
loginString := 'User ID=' + userName + ';Password=' + password;
Unfortunately such string concatenation might produce a non-valid login string. F.e. if the password value used contains special symblos like "
or =
then it should be escaped in
the resulting login string. While value escaping rules are very simple, they still need to be implemented by the user code.
Luckily Data Abstract provides a helper class that simplifies login string composition by providing the default string escaping implementation:
var login = new RemObjects.SDK.SemicolonSeparatedString();
login["User ID"] = userName;
login["Password"] = password;
var loginString = login.ToString();
login := TStringList.Create;
try
login.Delimiter := ';';
login.Values('User ID') := userName;
login.Values('Password') := password;
loginString := login.DelimitedText;
finally
login.Free;
end;
Calling LoginEx method
For Delphi and .NET, the proxy is created for BaseLoginService
(the ancestor of all DataAbstract Login services) and the LoginEx
method of the LoginService service is called. For Xcode, the DARemoteDataAdapter class provides login functionality out of the box via the loginWithString message for LoginEx.
(new RemObjects.DataAbstract.Server.BaseLoginService_Proxy
(message, clientChannel, "LoginService"))
.LoginEx("User=UserName;Password=UserPassword");
DynamicRequest.ParamByName('aLoginString').AsString :=
'User Id=UserName;Password=UserPassword';
DynamicRequest.Execute();
Dynamic Request setup:
lRemoteService := TRORemoteService.Create(nil);
lRemoteService.Channel := self.Channel;
lRemoteService.Message := self.Message;
lRemoteService.ServiceName :='LoginService';
lDynamicRequest := TRODynamicRequest.Create(nil);
lDynamicRequest.RemoteService := lRemoteService;
lDynamicRequest.MethodName := 'LoginEx';
lDynamicRequest.Params.Add('Result', rtBoolean, fResult);
lDynamicRequest.Params.Add('aLoginString', rtUTF8String, fIn);
[remoteDataAdapter loginWithString:@"User=UserName;Password=UserPassword"];
Summary
The LoginEx feature provides a unified, simple and easily extensible server login interface for client applications.