Delphi LDAP物件管理(使用者登入認證、組、組織)

左边江湖右边庙發表於2024-07-08

unit login;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, uniGUITypes, uniGUIAbstractClasses,
uniGUIClasses, uniGUIRegClasses, uniGUIForm, uniButton, uniGUIBaseClasses,
uniEdit, REST.Types, uniMemo, REST.Client, Data.Bind.Components,
Data.Bind.ObjectScope, system.json, system.Hash, uniImage, uniPanel,
Vcl.Imaging.pngimage, uniImageList, ActiveDs_TLB, ActiveX, system.Win.ComObj,
uniMainMenu;

type
TUniLoginForm1 = class(TUniLoginForm)
UserID: TUniEdit;
Password: TUniEdit;
UniButton1: TUniButton;
UniContainerPanel2: TUniContainerPanel;
UniImage1: TUniImage;
UniImageList1: TUniImageList;
procedure UniButton1Click(Sender: TObject);
procedure UniLoginFormReady(Sender: TObject);
procedure LoginADInfo(aUser, aPass, aDomainPath: WideString);
procedure PasswordKeyPress(Sender: TObject; var Key: Char);
private
{ Private declarations }
procedure LDAPLogin;
public
{ Public declarations }
end;

// 預設條件下,ADsGetObject函式根據當前使用者進行安全認證。
function ADsGetObject(lpszPathName: PWideChar; // 第一個引數是物件的路徑名
const riid: TIID; // 第二個引數是物件的介面識別符號
out obj): HResult; stdcall; external 'activeds.dll'; // 第三個引數用於返回得到的被請求的介面指標

// ADsOpenObject 函式在不同的安全認證機制下繫結 ADSI 物件,
// 它主要是透過呼叫引數返回的使用者名稱和口令來認證的
function ADsOpenObject(lpszPathName: PWideChar; // 第一個引數是物件的路徑名
lpszUserName: PWideChar; // 第二個引數是呼叫者提供的使用者名稱
lpszPassword: PWideChar; // 第三個引數是呼叫者提供的口令
dwReserved: LongInt; // 第四個引數是一個保留的 provider 標識,用來確定繫結的認證方法
const riid: TIID; // 第五個引數是請求介面的介面識別符號,
out obj): HResult; stdcall; external 'activeds.dll'; // 最後一個引數用來返回請求的介面指標。
function UniLoginForm1: TUniLoginForm1;

implementation

{$R *.dfm}

uses
uniGUIVars, MainModule, uniGUIApplication, Main;

function UniLoginForm1: TUniLoginForm1;
begin
Result := TUniLoginForm1(UniMainModule.GetFormInstance(TUniLoginForm1));
end;

procedure TUniLoginForm1.UniButton1Click(Sender: TObject);
begin
LDAPLogin;
end;

procedure TUniLoginForm1.LDAPLogin;
var
DomainPath, ADUser, ADPass: WideString;
begin
DomainPath := 'LDAP://192.168.162.250/DC=ttri,DC=com'; // LDAP訪問AD的路徑。
ADUser := UserID.Text + '@ttri.com'; // 注意使用者名稱稱的寫法:域名稱 + 使用者名稱稱 或 User@domain.com
// ADUser:='OAWebUser@Hebmc.com'; //注意使用者名稱稱的寫法:域名稱 + 使用者名稱稱 或 User@domain.com
ADPass := Password.Text; // 使用者密碼。
LoginADInfo(ADUser, ADPass, DomainPath);

end;

procedure TUniLoginForm1.LoginADInfo(aUser, aPass, aDomainPath: WideString);
var
UnknownObject: IUnknown;
Enum: IEnumVariant;
ADsTempObj: OLEVariant;
Domain: IADsContainer;
Container: IADsContainer;
ADsObj: IADs;
Value: LongWord;
userpath: string;
User: IADsUser;
grp: IAdsGroup;
grps: IAdsMembers;
varGroup: OLEVariant;
Temp: LongWord;
sGroupType: string;

begin
OleCheck(ADsOpenObject(PWideChar(aDomainPath), PWideChar(aUser),
PWideChar(aPass), 0, IID_IADsContainer, UnknownObject));

// 設定域物件
Domain := UnknownObject as IADsContainer;

// 獲取列舉物件,並賦值給 Enum 變數
Enum := (Domain._NewEnum) as IEnumVariant;

// 利用列舉物件查詢,把每個子物件賦值給臨時的 OLEVariant 物件
while (Enum.Next(1, ADsTempObj, Value) = S_OK) do
begin
ADsObj := IUnknown(ADsTempObj) as IADs; // 獲得臨時物件:OLEVariant 變數賦值給 ADSI 物件

if ADsObj.Class_ = 'user' then
// 如果是使用者物件  displayName    sAMAccountName  objectSID
begin
  if ADsObj.Get('sAMAccountName') = UserID.Text then
  begin
    userpath := ADsObj.ADsPath;
    MainForm.UniPanel3.Caption := ADsObj.Get('cn');
    user_id:=ADsObj.Get('sAMAccountName');
    ADsGetObject(PWideChar(userpath), IADsUser, User);
    // User.GetInfo;
    grps := User.Groups;
    Enum := grps._NewEnum as IEnumVariant;
    if Enum <> nil then
      group := TStringList.Create;

    begin
      while (Enum.Next(1, varGroup, Temp) = S_OK) do
      begin
        grp := IDispatch(varGroup) as IAdsGroup;
        group.Add(grp.Get('cn'));
        //MainForm.UniTreeView1.Items.Add(nil, grp.Get('cn'));
      end;
    end;
  end;
end;
LoginADInfo(aUser, aPass, ADsObj.ADsPath);
ADsTempObj := Null; // 釋放OLEVariant
varGroup := Null;
ModalResult := mrOK;

end;
end;

procedure TUniLoginForm1.PasswordKeyPress(Sender: TObject; var Key: Char);
begin
if key = #13 then
begin
UniButton1Click(sender);
end;
end;

procedure TUniLoginForm1.UniLoginFormReady(Sender: TObject);
begin
with UserID, JSInterface do
begin
JSCall('inputWrap.addCls', ['fa fa-user icon-textfield']);
JSCall('inputEl.setWidth', [Width - 2]);
end;
with Password, JSInterface do
begin
JSCall('inputWrap.addCls', ['fa fa-key icon icon-textfield']);
JSCall('inputEl.setWidth', [Width - 2]);
end;

end;

initialization

RegisterAppFormClass(TUniLoginForm1);

end.

相關文章