RAD Studio |  |

Controlling Server Login
See Also
Collapse All

Most remote database servers include security features to prohibit unauthorized access. Usually, the server requires a user name and password login before permitting database access.

At design time, if a server requires a login, a standard login dialog box prompts for a user name and password when you first attempt to connect to the database.

At runtime, there are three ways you can handle a server's request for a login:

The first way is to let the default login dialog and processes handle the login. This is the default approach. Set the LoginPrompt property of the connection component to True (the default) and add DBLogDlg to the uses clause of the unit that declares the connection component. Your application displays the standard login dialog box when the server requests a user name and password.

The second way is to supply the login information before the login attempt. Each type of connection component uses a different mechanism for specifying the user name and password:

- For BDE, dbExpress, and InterBase express datasets, the user name and password connection parameters can be accessed through the Params property. (For BDE datasets, the parameter values can also be associated with a BDE alias, while for dbExpress datasets, they can also be associated with a connection name).
- For ADO datasets, the user name and password can be included in the ConnectionString property (or provided as parameters to the Open method).

If you specify the user name and password before the server requests them, be sure to set the LoginPrompt to False, so that the default login dialog does not appear. For example, the following code sets the user name and password on a SQL connection component in the BeforeConnect event handler, decrypting an encrypted password that is associated with the current connection name:
Copy Code

    procedure TForm1.SQLConnectionBeforeConnect(Sender: TObject);
    begin
      with Sender as TSQLConnection do
      begin
        if LoginPrompt = False then
        begin
          Params.Values['User_Name'] := 'SYSDBA';
          Params.Values['Password'] := Decrypt(Params.Values['Password']);
        end;
      end;
    end;

Copy Code

    void __fastcall TForm1::SQLConnectionBeforeConnect(TObject *Sender)
    {
      if (SQLConnection1->LoginPrompt == false)
      {
        SQLConnection1->Params->Values["User_Name"] = "SYSDBA";
        SQLConnection1->Params->Values["Password"] =
            Decrypt(SQLConnection1->Params->Values["Password"]);
      }
    }

Note that setting the user name and password at design-time or using hard-coded strings in code causes the values to be embedded in the application's executable file. This still leaves them easy to find, compromising server security:

The third way is to provide your own custom handling for the login event. The connection component generates an event when it needs the user name and password.

- For TDatabase, TSQLConnection, and TIBDatabase, this is an OnLogin event. The event handler has two parameters, the connection component, and a local copy of the user name and password parameters in a string list. (TSQLConnection includes the database parameter as well). You must set the LoginPrompt property to True for this event to occur. Having a LoginPrompt value of False and assigning a handler for the OnLogin event creates a situation where it is impossible to log in to the database because the default dialog does not appear and the OnLogin event handler never executes.
- For TADOConnection, the event is an OnWillConnect event. The event handler has five parameters, the connection component and four parameters that return values to influence the connection (including two for user name and password). This event always occurs, regardless of the value of LoginPrompt.

Write an event handler for the event in which you set the login parameters. Here is an example where the values for the USER NAME and PASSWORD parameters are provided from a global variable (UserName) and a method that returns a password given a user name (PasswordSearch)
Copy Code

    procedure TForm1.Database1Login(Database: TDatabase; LoginParams: TStrings);
    begin
      LoginParams.Values['USER NAME'] := UserName;
      LoginParams.Values['PASSWORD'] := PasswordSearch(UserName);
    end;

Copy Code

    void __fastcall TForm1::Database1Login(TDatabase *Database, TStrings *LoginParams)
    {
      LoginParams->Values["USER NAME"] = UserName;
      LoginParams->Values["PASSWORD"] = PasswordSearch(UserName);
    }

As with the other methods of providing login parameters, when writing an OnLogin or OnWillConnect event handler, avoid hard coding the password in your application code. It should appear only as an encrypted value, an entry in a secure database your application uses to look up the value, or be dynamically obtained from the user.

See Also

Using Implicit Connections

Controlling Connections

Managing Transactions

Working with Associated Datasets

Sending Commands to the Server

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!