加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何将Delphi与Active Directory集成?

发布时间:2020-12-15 10:05:53 所属栏目:大数据 来源:网络整理
导读:我们需要使用Delphi 7验证Microsoft Active Directory上的用户,那么最好的方法是什么? 我们可以有两种情况:用户输入其网络用户名和密码,用户名可能包含域名,如果它是一个有效的用户,我们会检查活动目录.或者我们从Windows获取当前记录的用户,并检查AD是否
我们需要使用Delphi 7验证Microsoft Active Directory上的用户,那么最好的方法是什么?

我们可以有两种情况:用户输入其网络用户名和密码,用户名可能包含域名,如果它是一个有效的用户,我们会检查活动目录.或者我们从Windows获取当前记录的用户,并检查AD是否仍然有效.

第一种情况需要用户验证,而第二种情况只是简单的AD搜索和定位.

有没有人知道执行上述一种或两种情况的组件或代码?

解决方法

这是我们写和使用的单位.简单,完成工作.
unit ADSI;

interface

uses
  SysUtils,Classes,ActiveX,Windows,ComCtrls,ExtCtrls,ActiveDs_TLB,adshlp,oleserver,Variants;

type
  TPassword = record
    Expired: boolean;
    NeverExpires: boolean;
    CannotChange: boolean;
end;

type
  TADSIUserInfo = record
    UID: string;
    UserName: string;
    Description: string;
    Password: TPassword;
    Disabled: boolean;
    LockedOut: boolean;
    Groups: string; //CSV
end;

type
  TADSI = class(TComponent)

  private
    FUserName:  string;
    FPassword:  string;
    FCurrentUser: string;
    FCurrentDomain: string;

    function GetCurrentUserName: string;
    function GetCurrentDomain: string;


  protected
    { Protected declarations }
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    property CurrentUserName: string read FCurrentUser;
    property CurrentDomain: string read FCurrentDomain;

    function GetUser(Domain,UserName: string; var ADSIUser: TADSIUserInfo): boolean;
    function Authenticate(Domain,UserName,Group: string): boolean;

  published
    property LoginUserName: string read FUserName write FUserName;
    property LoginPassword: string read FPassword write FPassword;
  end;

procedure Register;

implementation


function ContainsValComma(s1,s: string): boolean; 
var 
  sub,str: string; 
begin 
  Result:=false; 
  if (s='') or (s1='') then exit; 
  if SameText(s1,s) then begin 
    Result:=true; 
    exit; 
  end; 
  sub:=','+lowercase(trim(s1))+','; str:=','+lowercase(trim(s))+','; 
  Result:=(pos(sub,str)>0); 
end;

procedure Register;
begin
  RegisterComponents('ADSI',[TADSI]);
end;

constructor TADSI.Create(AOwner: TComponent);
begin
   inherited Create(AOwner);

   FCurrentUser:=GetCurrentUserName;
   FCurrentDomain:=GetCurrentDomain;
   FUserName:='';
   FPassword:='';
end;

destructor TADSI.Destroy;
begin

   inherited Destroy;
end;

function TADSI.GetCurrentUserName : string;
const
  cnMaxUserNameLen = 254;
var
  sUserName     : string;
  dwUserNameLen : DWord;
begin
  dwUserNameLen := cnMaxUserNameLen-1;
  SetLength(sUserName,cnMaxUserNameLen );
  GetUserName(PChar(sUserName),dwUserNameLen );
  SetLength(sUserName,dwUserNameLen);
  Result := sUserName;
end;

function TADSI.GetCurrentDomain: string;
const
  DNLEN = 255;
var
  sid               : PSID;
  sidSize           : DWORD;
  sidNameUse        : DWORD;
  domainNameSize    : DWORD; 
  domainName        : array[0..DNLEN] of char;

begin
  sidSize := 65536; 
  GetMem(sid,sidSize); 
  domainNameSize := DNLEN + 1;
  sidNameUse := SidTypeUser;
  try
     if LookupAccountName(nil,PChar(FCurrentUser),sid,sidSize,domainName,domainNameSize,sidNameUse) then
         Result:=StrPas(domainName);
  finally
    FreeMem(sid);
  end;
end;

function TADSI.Authenticate(Domain,Group: string): boolean;
var
  aUser: TADSIUserInfo;
begin
  Result:=false;
  if GetUser(Domain,aUser) then begin
     if not aUser.Disabled and not aUser.LockedOut then begin
        if Group='' then
           Result:=true
        else
           Result:=ContainsValComma(Group,aUser.Groups);
     end;
  end;
end;

function TADSI.GetUser(Domain,UserName: string; var ADSIUser: TADSIUserInfo): boolean;
var
  usr   :    IAdsUser;
  flags :    integer;
  Enum  :    IEnumVariant;
  grps  :    IAdsMembers;
  grp   :    IAdsGroup;
  varGroup : OleVariant;
  Temp :     LongWord;
  dom1,uid1: string;

  //ui: TADSIUserInfo;

begin
  ADSIUser.UID:='';
  ADSIUser.UserName:='';
  ADSIUser.Description:='';
  ADSIUser.Disabled:=true;
  ADSIUser.LockedOut:=true;
  ADSIUser.Groups:='';
  Result:=false;

  if UserName='' then
     uid1:=FCurrentUser
  else
     uid1:=UserName;

  if Domain='' then
     dom1:=FCurrentDomain
  else
     dom1:=Domain;

  if uid1='' then exit;
  if dom1='' then exit;

  try
     if trim(FUserName)<>'' then
        ADsOpenObject('WinNT://' + dom1 + '/' + uid1,FUserName,FPassword,1,IADsUser,usr)
     else
        ADsGetObject('WinNT://' + dom1 + '/' + uid1,usr);

     if usr=nil then exit;

     ADSIUser.UID:= UserName;
     ADSIUser.UserName := usr.FullName;
     ADSIUser.Description := usr.Description;
     flags := usr.Get('userFlags');
     ADSIUser.Password.Expired := usr.Get('PasswordExpired');
     ADSIUser.Password.CannotChange := (flags AND ADS_UF_PASSWD_CANT_CHANGE)<>0;
     ADSIUser.Password.NeverExpires := (flags and ADS_UF_DONT_EXPIRE_PASSWD)<>0;
     ADSIUser.Disabled := usr.AccountDisabled;
     ADSIUser.LockedOut := usr.IsAccountLocked;

     ADSIUser.Groups:='';
     grps := usr.Groups;
     Enum := grps._NewEnum as IEnumVariant;
     if Enum <> nil then begin
       while (Enum.Next(1,varGroup,Temp) = S_OK) do begin
         grp := IDispatch(varGroup) as IAdsGroup;
         //sGroupType := GetGroupType(grp);
         if ADSIUser.Groups<>'' then ADSIUser.Groups:=ADSIUser.Groups+',';
         ADSIUser.Groups:=ADSIUser.Groups+grp.Name;
         VariantClear(varGroup);
       end;
     end;
     usr:=nil;
     Result:=true;
  except
     on e: exception do begin
        Result:=false;
        exit;
     end;
  end;
end;

end.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读