Вопрос, поднятый в данном запросе, касается интеграции C# .NET библиотеки для аутентификации через LDAPS в устаревшем приложении на Delphi 5. Для решения этой задачи необходимо создать COM-сервер в C#, который будет общаться с Delphi-приложением.
Описание проблемы
Приложение на Delphi 5 использует аутентификацию против LDAP/AD, но не поддерживает работу с LDAPS (LDAP/SSL) через порты 636 или 3269. В C# аутентификация может быть выполнена с помощью простой функции:
PrincipalContext pc = new PrincipalContext(ContextType.Domain, "testnet.testad.org:636", "dc=testnet,dc=testad,dc=org");
bool validated = pc.ValidateCredentials(username, password, ContextOptions.Negotiate);
Для использования этой функции в Delphi 5, необходимо обернуть её в .DLL, который затем будет вызван из Delphi-приложения.
Подход к решению
Для взаимодействия между Delphi 5 и C# .NET библиотекой, можно использовать COM-объект. Это позволит вызвать функции C# из Delphi, несмотря на их различное окружение выполнения. Одним из инструментов, упомянутых в контексте, является пакет UnmanagedExports, который упрощает экспорт функций из C# в COM-совместимый интерфейс.
Пример реализации
Создаем интерфейс для функциональности:
type
IManagedInterface = interface
['{9F5A2431-5559-410C-BAB4-5144CA8C0B7B}']
function CheckCredentials(AContextName, AContainerName, AUserName,
APassword: WideString): Integer; safecall;
end;
Создаем Class Library (.NET Framework) в Visual Studio 2019, нацеленный на x86:
[ComVisible(true)]
[Guid("9F5A2431-5559-410C-BAB4-5144CA8C0B7B")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IManagedInterface
{
int CheckCredentials(
[MarshalAs(UnmanagedType.BStr)] string contextname,
[MarshalAs(UnmanagedType.BStr)] string container,
[MarshalAs(UnmanagedType.BStr)] string username,
[MarshalAs(UnmanagedType.BStr)] string password);
}
public class Class1 : IManagedInterface
{
public int CheckCredentials(string contextname, string container,
string username, string password)
{
var pc = new PrincipalContext(ContextType.Domain, contextname, container);
return Convert.ToInt32(pc.ValidateCredentials(username, password,
ContextOptions.Negotiate));
}
}
Экспортируем функцию создания экземпляра класса:
static class Exports
{
[DllExport]
public static void CreateTheInterface(
[MarshalAs(UnmanagedType.Interface)] out IManagedInterface instance)
{
instance = new Class1();
}
}
Используем созданный DLL в Delphi:
procedure CreateTheInterface(out AInstance: IManagedInterface); stdcall;
external 'ClassLibrary1.dll';
var
Imi: IManagedInterface;
context, container, username, password: string;
begin
CreateTheInterface(Imi);
if Imi <> nil then try
context := 'testnet.testad.org:636';
container := 'dc=testnet,dc=testad,dc=org';
username := 'someguy';
password := 'password';
Writeln('call returned: ', Imi.CheckCredentials(context, container, username, password));
except
on E: Exception do
Writeln(E.Message);
end;
Readln;
end.
Заключение
Создание COM-сервера с использованием UnmanagedExports позволяет успешно интегрировать C# .NET библиотеку для аутентификации через LDAPS в Delphi 5 приложение, не требуя сложных настроек и избегая "мины" в процессе интеграции.
Проблема заключается в необходимости интеграции C# .NET библиотеки для аутентификации через LDAPS в устаревшее приложение на Delphi 5 с использованием COM-сервера.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS