Я создаю класс, который позволит открывать окно аутентификации, и пользователь вводит домен \ имя пользователя и пароль для аутентификации в Active Directory. У меня есть рабочий код ниже, но теперь я хочу пройти аутентификацию по указанной группе c AD, в которой находится пользователь. Я не знаю, как лучше всего реализовать этот код, и мне трудно с этим . LOGONUSER может пройти аутентификацию в группе безопасности AD? Приветствуется любая помощь.
т.е. если пользователь Admin находится в группе «AD_CanAccessApp». Этот пользователь сможет получить доступ после ввода домена / имени пользователя и пароля и аутентификации по AD.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Win.ScktComp;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function getDomain: string;
var
vlDomainName : array[0..MAXCHAR] of char;
vlSize : ^DWORD;
begin
New(vlSize);
vlSize^ := MAXCHAR;
ExpandEnvironmentStrings(PChar('%USERDOMAIN%'), vlDomainName, vlSize^);
Dispose(vlSize);
Result := vlDomainName;
end;
function IsAdmin: Boolean;
const
SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority =
(Value: (0, 0, 0, 0, 0, 5));
SECURITY_BUILTIN_DOMAIN_RID = $00000020;
DOMAIN_ALIAS_RID_ADMINS = $00000220;
var
hAccessToken: THandle;
ptgGroups: PTokenGroups;
{$IFDEF FPC}dwInfoBufferSize: PDWORD;{$ELSE}dwInfoBufferSize: DWORD;{$ENDIF}
psidAdministrators: PSID;
x: Integer;
bSuccess: BOOL;
begin
if Win32Platform <> VER_PLATFORM_WIN32_NT then
begin
Result := True;
exit;
end;
Result := False;
bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
hAccessToken);
if not bSuccess then
begin
if GetLastError = ERROR_NO_TOKEN then
bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
hAccessToken);
end;
if bSuccess then
begin
GetMem(ptgGroups, 1024);
bSuccess := GetTokenInformation(hAccessToken, TokenGroups,
ptgGroups, 1024, dwInfoBufferSize);
CloseHandle(hAccessToken);
if bSuccess then
begin
AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, psidAdministrators);
{$R-}
for x := 0 to ptgGroups.GroupCount - 1 do
if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then
begin
Result := True;
break;
end;
{$R+}
FreeSid(psidAdministrators);
end;
FreeMem(ptgGroups);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
const
DNLEN = 255;
var
sid : PSID;
sidSize : DWORD;
sidNameUse : DWORD;
domainNameSize : DWORD;
domainName : array[0..DNLEN] of char;
x : string;
hToken : THandle;
begin
sidSize := 65536;
GetMem(sid, sidSize);
domainNameSize := DNLEN + 1;
sidNameUse := SidTypeUser;
try
if LookupAccountName(nil, PChar(Edit1.Text), sid, sidSize,
domainName, domainNameSize, sidNameUse) then
x:=StrPas(domainName);
finally
FreeMem(sid);
end;
//showmessage(x);
if edit3.Text = x then
begin
if (LogonUser(pChar(edit1.Text), pChar(edit3.Text), pChar(edit2.Text), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hToken)) then
begin
CloseHandle(hToken);
showmessage('logon successful');
end
else
showmessage('Failed logon! Username or password incorrect!');
end
else showmessage('Failed logon! Domain name incorrect!');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if IsAdmin then showmessage('it''s an administrator')
else showmessage('it''s a simple user');
end;
end.
Спасибо
john