FW user login to authenticate from windows active directory

User avatar
fraxzi
Posts: 811
Joined: Tue May 06, 2008 4:28 am
Location: Philippines
Contact:

FW user login to authenticate from windows active directory

Post by fraxzi »

Dear All,

It's been a while.. busy with FWH projects..

Anyone here who can authenticate/validate a logon from FW apps to Windows Active Directory?

Kind regards,
Frances
Kind Regards,
Frances

Fivewin for xHarbour v18.07
xHarbour v1.2.3.x
BCC 7.3 + PellesC8 ( Resource Compiler only)
ADS 10.1 / MariaDB
Crystal Reports 8.5/9.23 DE
xMate v1.15
User avatar
Rick Lipkin
Posts: 2397
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: FW user login to authenticate from windows active directory

Post by Rick Lipkin »

Frances

Since Active directory creates a user profile for each user on any computer .. it is very easy to get the login userId ..

Rick Lipkin

Code: Select all

xLOGIN := substr(upper(WNetGetuser()+space(25)),1,25)   // fivewin
 
ps .. after re-reading your post .. are you trying to run your application from a desktop and authendicating to a database ? .. or clicking on just a shortcut to your program on a network share ?

Active directory or eDir from Novell work and authenticate just fine if you point your shortcut to a unc \\server\share\yourapp\app.exe .. you do not really need to login, if your userid has the proper credentials to your share .. a unc is all you need.
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: FW user login to authenticate from windows active directory

Post by nageswaragunupudi »

I personally design all our network software to authenticate users by their windows user name (wnetgetuser()) rather than maintaining separate login for the application.
Regards

G. N. Rao.
Hyderabad, India
User avatar
Carles
Posts: 937
Joined: Fri Feb 10, 2006 2:34 pm
Location: Barcelona
Contact:

Re: FW user login to authenticate from windows active directory

Post by Carles »

Hi,

U can try this code to acces LDAP.

Code: Select all

#include 'fivewin.ch'
#include "ado.ch"
#include "xBrowse.ch"

#define MI_DOMINIO          'LDAP://ajtarragona.es'

#define ADS_SCOPE_BASE      0
#define ADS_SCOPE_ONELEVEL  1
#define ADS_SCOPE_SUBTREE   2

STATIC oCon

*--------------
FUNCTION Main()
*--------------
    LOCAL aData

    IF ConectaLDAP()

       MsgRun( "Carregant dades del LDAP...", 'Sistema', ;
              {|o| aData := SelectUsers() } )

    ENDIF

RETU NIL

*---------------------
FUNCTION ConectaLDAP()
*---------------------
   LOCAL lOk    := .F.
   LOCAL oError

   TRY

     oCon          := TOleAuto():new("ADODB.Connection")

     oCon:Provider := 'ADsDSOObject'

     oCon:Open( "Active Directory Provider" )

     lOk           := .T.


    CATCH oError

      xBrowse( oError )

   END

RETU lOk

*----------------------------
STATIC FUNCTION SelectUsers()
*----------------------------
   LOCAL oRs, oProp, oError, o
   LOCAL nLen    := 0
   LOCAL cString := ''
   LOCAL cWhere  := ''
   LOCAL aData   := {}
   LOCAL aHead   := {}


   TRY

     oRs             := TOleAuto():new("ADODB.Command")

     oRs:ActiveConnection := oCon


     cString         := "SELECT "              + ;
                        " displayName,"        + ;
                        " distinguishedName,"  + ;
                        " mail,"               + ;
                        " telephoneNumber,"    + ;
                        " mobile,"             + ;
                        " department,"         + ;
                        " sAMAccountname"      + ;
                        ""                     + ;
                        " FROM '" + MI_DOMINIO + "'"

      cWhere         :=  " WHERE objectCategory   = 'person' AND" + ;
                         "       objectClass      = 'user'   AND" + ;
                         "     ( telephoneNumber  = '*'      OR " + ;
                         "       mobile           = '*' )       " + ;
                         " ORDER BY telephoneNumber"

*                         " ORDER BY displayName"


     oRs:CommandText := cString + cWhere

     oProp           := oRs:Properties( 'SearchScope' )
     oProp:value     := ADS_SCOPE_SUBTREE

     oProp           := oRs:Properties( 'Page size' )
     oProp:value     := 2000

     o := oRs:Execute()

    CATCH oError

      xBrowse( oError )

   END

   nLen  := LoadData( o, @aData, @aHead )


   IF nLen > 0

      Table( aData, aHead, 'Total: ' + ltrim(str(nLen)) )

     ELSE

      Alert( 'No data !' )

   ENDIF


RETU aData


*------------------------------------
FUNCTION AdoError( oError, lMessage )
*------------------------------------
    LOCAL cError := .T.

    DEFAULT lMessage := .T.

    cError := "Descripción  "  + Chr( VK_TAB) + ": " + oError:Description              + CRLF + CRLF +  ;
              "Error Nativo  " + Chr( VK_TAB) + ": "  + Ltrim(Str(oError:NativeError)) + CRLF + ;
              "Número Error  " + Chr( VK_TAB) + ": "  + Ltrim(Str(oError:Number))      + CRLF + ;
              "Origen        " + Chr( VK_TAB) + ": "  + oError:Source                  + CRLF + ;
              "EszAdo SQL  "   + Chr( VK_TAB) + ": "  + oError:SQLState

    IF lMessage
       MsgStop( cError, 'Ado Connection' )
    ENDIF

RETU cError

*------------------------
FUNCTION ShowInfo( oCon )
*------------------------
    LOCAL cInfo      := ''

    cInfo += 'Version Ado       '  + Chr( VK_TAB ) + Chr( VK_TAB ) + ': '  + Alltrim( cValToChar( oCon:Version()            )) + CRLF
    cInfo += 'Provider          '  + Chr( VK_TAB ) + Chr( VK_TAB ) + ': '  + Alltrim( cValToChar( oCon:Provider()           )) + CRLF
    cInfo += 'Mode              '  + Chr( VK_TAB ) + Chr( VK_TAB ) + ': '  + Alltrim( cValToChar( oCon:Mode()               )) + CRLF
    cInfo += 'State             '  + Chr( VK_TAB ) + Chr( VK_TAB ) + ': '  + Alltrim( cValToChar( oCon:State()              )) + CRLF
    cInfo += 'CursorLocation    '  + Chr( VK_TAB ) + Chr( VK_TAB ) + ': '  + Alltrim( cValToChar( oCon:CursorLocation()     )) + CRLF
    cInfo += 'Connection TimeOut'  + Chr( VK_TAB ) + ': '  + Alltrim( cValToChar( oCon:ConnectionTimeOut()  )) + CRLF
    cInfo += 'Command TimeOut   '  + Chr( VK_TAB ) + ': '  + Alltrim( cValToChar( oCon:CommandTimeOut()     )) + CRLF + CRLF
    cInfo += 'Connection String '  + CRLF
    cInfo += oCon:ConnectionString()

    MsgInfo( cInfo, 'Info Connection' )

RETU NIL

*---------------------------------------------------
FUNCTION Table( aValues, aHeaders, cTitle, lSelect )
*---------------------------------------------------
    LOCAL oDlg, oBrw, oFont
    LOCAL nI
    LOCAL nPos := 0

    DEFAULT aHeaders := {}
    DEFAULT cTitle   := 'Seleccione...'
    DEFAULT lSelect  := .T.

    IF ValType( aValues ) <> 'A'
       MsgAlert( aValues, 'Not table' )
       RETU 0
    ENDIF

    IF ValType( aHeaders ) == 'C'
       aHeaders := { aHeaders }
    ENDIF

    IF Len( avalues ) == 0
       MsgAlert( 'Table is empty !', 'LDAP Error' )
       RETU 0
    ENDIF

    DEFINE FONT oFont    NAME 'Courier New' SIZE NIL, -11

    DEFINE DIALOG oDlg TITLE cTitle FROM 0, 0 TO 20, 90
                  oDlg:lHelpIcon := .f.
                  oDlg:nStyle    := nOr( WS_THICKFRAME, WS_SYSMENU, WS_MINIMIZEBOX, WS_MAXIMIZEBOX )

       @ 0, 0 XBROWSE oBrw OF oDlg ARRAY aValues // AUTOSORT

            oBrw:SetArray( aValues )
            oBrw:SetColor( CLR_RED, CLR_WHITE )
            oBrw:SetFont( oFont )

            FOR nI := 1 TO Len( aHeaders )
                oBrw:aCols[nI]:cHeader := aHeaders[nI]
            NEXT

            IF Len( oBrw:aCols ) == 1

            ENDIF

            oBrw:blDblClick := {|| ( nPos := oBrw:nArrayAt, ;
                                     IF( lSelect, oDlg:End(),;
                                                  Table( aValues[nPos],,str(nPos), .F.);
                                       );
                                   )}
            oBrw:bKeyChar   := {|nKey| IF( nKey == VK_RETURN, Eval( oBrw:blDblClick ), )}

            oBrw:CreateFromCode()

            oDlg:oClient = oBrw

    ACTIVATE DIALOG oDlg CENTERED ;
             ON INIT ( SetupBar( oDlg )  ,;
                       XecValues( oDlg, oBrw, aValues )  ,;
                       oDlg:Resize() )

RETU nPos

*-------------------------------
STATIC FUNCTION SetupBar( oDlg )
*-------------------------------
    LOCAL oBar, oHand

    DEFINE CURSOR oHand HAND

    DEFINE BUTTONBAR oBar TOP _3D SIZE 23,23 OF oDlg
    DEFINE BUTTON  OF oBar       NOBORDER NAME '16Exit' ACTION oDlg:End()

    AEval( oBar:aControls,  {|x| x:oCursor := oHand } )

RETU NIL


*-----------------------------------------------
STATIC FUNCTION XecValues( oDlg, oBrw, aValues )
*-----------------------------------------------
    LOCAL nMax := 0


    IF Len( oBrw:aCols ) > 1
       RETU NIL
    ENDIF

    AEval( aValues, {|x| nMax := Max( nMax,;
           if( valtype(x) =='C', oDlg:GetWidth(Upper(x), oBrw:oFont), 0 ) ) } )

    nMax := IF( nMax > oBrw:nWidth, oBrw:nWidth, nMax )

    oBrw:aCols[1]:nWidth := nMax + 50

    oBrw:Refresh(.t.)

RETU NIL


*--------------------------------------------
STATIC FUNCTION LoadData( oRs, aData, aHead )
*--------------------------------------------
   LOCAL nLen    := 0
   LOCAL nFields := oRs:Fields:Count
   LOCAL nI
   LOCAL aReg

   aData := {}
   aHead := {}


   for nI := 0 TO nFields - 1
     Aadd( aHead, oRs:Fields(nI):name )
   next

   nLen := oRs:RecordCount()

   IF nLen > 0

      oRs:movefirst()

      WHILE !oRs:Eof()

          aReg := {}

          FOR nI := 1 TO Len(aHead)
              Aadd( aReg, oRs:Fields( aHead[nI] ):value )
          NEXT

          Aadd( aData, aReg )

          oRs:MoveNext()

      END

   ENDIF

RETU nLen
 
Salutacions, saludos, regards

"...programar es fácil, hacer programas es difícil..."

https://modharbour.app
https://modharbour.app/compass
https://forum.modharbour.app
User avatar
fraxzi
Posts: 811
Joined: Tue May 06, 2008 4:28 am
Location: Philippines
Contact:

Re: FW user login to authenticate from windows active directory

Post by fraxzi »

Dear All,

Sorry just got back from vacation.

Thanks for your reply..


What i am trying to do is to validate user login from FW app to authenticated domain user..

How to know if the user's login from FW app is valid domain user..

example:

user: FWUser
password: *****

validate FWUser and password to domain and return if the user/password is correct.. sort of.

Kind regards.
Kind Regards,
Frances

Fivewin for xHarbour v18.07
xHarbour v1.2.3.x
BCC 7.3 + PellesC8 ( Resource Compiler only)
ADS 10.1 / MariaDB
Crystal Reports 8.5/9.23 DE
xMate v1.15
User avatar
fraxzi
Posts: 811
Joined: Tue May 06, 2008 4:28 am
Location: Philippines
Contact:

Re: FW user login to authenticate from windows active directory

Post by fraxzi »

nageswaragunupudi wrote:I personally design all our network software to authenticate users by their windows user name (wnetgetuser()) rather than maintaining separate login for the application.

Dear Rao,

what if the FW user login is different from logged windows user.. How do you validate FW from domain user?

Kind regards.
Kind Regards,
Frances

Fivewin for xHarbour v18.07
xHarbour v1.2.3.x
BCC 7.3 + PellesC8 ( Resource Compiler only)
ADS 10.1 / MariaDB
Crystal Reports 8.5/9.23 DE
xMate v1.15
User avatar
fraxzi
Posts: 811
Joined: Tue May 06, 2008 4:28 am
Location: Philippines
Contact:

Re: FW user login to authenticate from windows active directory

Post by fraxzi »

Carles wrote:Hi,

U can try this code to acces LDAP.

Dear Carles,

Thanks for the code.. I will try it to retrieve LDAP users from domain.

But what I am trying to do is to validate FW user login as valid domain user.. which authenticates FW user/password to domain or from LDAP..

Kind regards.
Kind Regards,
Frances

Fivewin for xHarbour v18.07
xHarbour v1.2.3.x
BCC 7.3 + PellesC8 ( Resource Compiler only)
ADS 10.1 / MariaDB
Crystal Reports 8.5/9.23 DE
xMate v1.15
User avatar
Rick Lipkin
Posts: 2397
Joined: Fri Oct 07, 2005 1:50 pm
Location: Columbia, South Carolina USA

Re: FW user login to authenticate from windows active directory

Post by Rick Lipkin »

Frances
Dear Rao,

what if the FW user login is different from logged windows user.. How do you validate FW from domain user?

Kind regards.
When any person logs into a Domain from any pc .. that persons profile is automatically created on that pc and synchronized to AD. WNetGetUser() will always returned the logged in user.

Rick Lipkin
User avatar
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: FW user login to authenticate from windows active directory

Post by nageswaragunupudi »

Frances

I do not maintain separate list of users and passwords.
Domain user name is the application's user name. Since passwords are handled by the Domain, FW app does not need to worry about password maintenance. Any user remembers his domain password only and need not remember different passwords for different applications. In large organisations, employees feel more confident using domain passwords, because nobody (even system administrators) can read their passwords and they are confident that nobody can misuse their passwords.

Applcation decides user rights based on JobRoles assigned to a user but not on the basis of username. Application maintains a database mapping usernames to Locations and JobRoles. UserAdminstration interface allows administrators to assign jobroles and modify when the users are transferred or anybody leaves.
Regards

G. N. Rao.
Hyderabad, India
User avatar
Baxajaun
Posts: 853
Joined: Wed Oct 19, 2005 2:17 pm
Location: Gatika. Bizkaia

Re: FW user login to authenticate from windows active directory

Post by Baxajaun »

Dear Mr. Rao,

could you post a small sample ?

Thanks in advance !!!

Best regards,
User avatar
hebert_j_vargas
Posts: 94
Joined: Thu Aug 02, 2012 3:21 pm

Re: FW user login to authenticate from windows active directory

Post by hebert_j_vargas »

fraxzi wrote:Dear All,

It's been a while.. busy with FWH projects..

Anyone here who can authenticate/validate a logon from FW apps to Windows Active Directory?

Kind regards,
Frances
Hi Fraxi, I found this VB script, transtale to Visual Basic on EXCEL, and tested Worked Fine.

Code: Select all

Private Sub CommandButton1_Click()
        If Authenticated(TextBox1.Value, TextBox2.Value) Then
           MsgBox "Usuario Validado"
        Else
           MsgBox "Usuario / Contraseña Invalidos"
        End If
End Sub
Private Sub CommandButton2_Click()
        Application.Quit
End Sub
Function Authenticated(strUserID As String, strPassword As String, Optional strDNSDomain As String = "") As Boolean
         If strDNSDomain = "" Then
            Set objRootDSE = GetObject("LDAP://RootDSE")
            strDNSDomain = objRootDSE.Get("defaultNamingContext")
         End If

         'Authenticate
         Set dso = GetObject("LDAP:")
         On Error Resume Next
         Err.Clear
         Set ou = dso.OpenDSObject("LDAP://" & strDNSDomain, strUserID, strPassword, 1)
         Authenticated = (Err.Number = 0)
End Function
Then Translate to Xharbourd FW

Code: Select all

#include 'fivewin.ch'
#include "ado.ch"
#include "xBrowse.ch"

PROC Main()
      LOCAL cUser := SPACE(20)
      LOCAL cPssw := SPACE(20)
      If MsgGet( "Autenticación de usuarios", "Nombre de Usuario:", @cUser)
         If MsgGet( "Autenticación de usuarios", "Contraseña:", @cPssw)
            If Authenticated( alltrim(cUser), alltrim(cPssw) )
               MsgInfo("Usuario Correcto")
            Else
               MsgStop("Usuario Incorrecto")
            Endif
         Endif
      Endif
RETURN

Function Authenticated(cUserID, cPassword, cDNSDomain)
         local oRootDSE, oDSO, oU, lError
     
         default cDNSDomain := "DC=pdvsa,DC=com"
         TRY
            oRootDSE := GetActiveObject("LDAP://RootDSE")
         CATCH
            oRootDSE := CreateObject("LDAP:",cUserID,cPassword)
         END

         If empty( cDNSDomain )
            cDNSDomain := oRootDSE:Get( "defaultNamingContext" )
         EndIf
       
        TRY
           oDSO := GetActiveObject( "LDAP:" )
           oU := oDSO:OpenDSObject( "LDAP://" +  cDNSDomain, cUserID, cPassword, 1 ) //ADS Fast Bind
           lError := .f.
        CATCH
           lError := .t.
        END
RETURN (!lError)
This, doens't worked, GetActiveObject allways returned NIL.

I hope it's help to find your answer, I can't find any solution.
Compiler version: xHarbour 1.2.3 Intl. (SimpLex) (Build 20141106)
FiveWin Version: FWHX 15.01
BCC 5.8.2
User avatar
hebert_j_vargas
Posts: 94
Joined: Thu Aug 02, 2012 3:21 pm

Re: FW user login to authenticate from windows active directory

Post by hebert_j_vargas »

I Forgot to mention, to test Vb script on excel, you need to create an userform name "userform1", then add 2 control textbox controls (textbox1 = username, textbox2 = password), then two commadbuttom and assign CommandButton1_Click(), CommandButtom2_Click(). the last thing to do is assign the next procedure to worksheet1.

Code: Select all

Private Sub Workbook_Open()
        UserForm1.Show
End Sub
That's all.

Please let me know if you succeed.
Compiler version: xHarbour 1.2.3 Intl. (SimpLex) (Build 20141106)
FiveWin Version: FWHX 15.01
BCC 5.8.2
User avatar
fraxzi
Posts: 811
Joined: Tue May 06, 2008 4:28 am
Location: Philippines
Contact:

Re: FW user login to authenticate from windows active directory

Post by fraxzi »

Thanks Hebert.

Thank you for this update. If I have time I will try this.. somehow I abandoned the idea :)
Kind Regards,
Frances

Fivewin for xHarbour v18.07
xHarbour v1.2.3.x
BCC 7.3 + PellesC8 ( Resource Compiler only)
ADS 10.1 / MariaDB
Crystal Reports 8.5/9.23 DE
xMate v1.15
User avatar
Baxajaun
Posts: 853
Joined: Wed Oct 19, 2005 2:17 pm
Location: Gatika. Bizkaia

Re: FW user login to authenticate from windows active directory

Post by Baxajaun »

Hi Herbert,

here in line 29:

oRootDSE := CreateObject("LDAP://",cUserID,cPassword)

Error description: Error TOleAuto/-1 CO_E_CLASSSTRING: TOLEAUTO:NEW
Args:
[ 1] = C LDAP://
[ 2] = U
[ 3] = C FPGRANDE

Thanks in advance.

Regards
User avatar
hebert_j_vargas
Posts: 94
Joined: Thu Aug 02, 2012 3:21 pm

Re: FW user login to authenticate from windows active directory

Post by hebert_j_vargas »

fraxzi wrote:Thanks Hebert.

Thank you for this update. If I have time I will try this.. somehow I abandoned the idea :)
It's a shame :( , I think this procedure is a good idea.
Compiler version: xHarbour 1.2.3 Intl. (SimpLex) (Build 20141106)
FiveWin Version: FWHX 15.01
BCC 5.8.2
Post Reply