Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Κλήση εξωτερικής εφαρμογής ως διαφορετικός user (.NET 1.1, API call)

Îåêßíçóå áðü ôï ìÝëïò cap. Τελευταία δημοσίευση από το μέλος Panagiotis Kefalidis στις 09-12-2005, 22:41. Υπάρχουν 5 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  09-12-2005, 12:09 7734

    Κλήση εξωτερικής εφαρμογής ως διαφορετικός user (.NET 1.1, API call)

    Εχω το εξής θέμα:

    Χρειάζεται να καλέσω μια εφαρμογή (για την ακρίβεια, ΙΕ με ένα συγκεκριμένο URL) ως ένας συγκεκριμένος χρήστης (και όχι προφανώς αυτός που τρέχει την αρχική εφαρμογή) μέσα από μια άλλη εφαρμογή.

    Χρησιμοποιώ .NET 1.1 οπότε η System.Diagnostics.Process.CreateProcess δεν με καλύπτει μια και δεν μπορεί να δεχθεί user credentials (σε αντίθεση με το .NET 2.0).

    Αρα η μόνη λύση στην οποία μπορούσα να καταφύγω ήταν API Call. Δεν έχω μεγάλη γνώση από αυτόν τον τομέα, με πολύ κόπο κατάφερα να βρω κώδικα σε C# τον οποίο άλλαξα σε VB.NET και ενσωματωσα σε μια δική μου κλάση και δουλεύει. Χρησιμοποιεί το advapi32.dll και συγκεκριμένα την CreateProcessWithLogonW(). Θα σας παραθέσω τον κώδικα παρακάτω μια και είναι χρήσιμος άν κάποιος άλλος συνάδελφος θέλει να κάνει το ίδιο πράγμα.

    Το πρόβλημα

    Η CreateProcessWithLogonW δουλεύει μόνο σε Win2000/2003. Ο πελάτης (δυστυχώς) έχει και παλιότερα συστήματα όπως NT 4.0 Workstation. Αυτό είναι κάτι που δεν μπορώ να αλλάξω.

    Ψάχνοντας, βρήκα οτι η CreateProcessAsUser() γενικά παίζει και σε αυτά τα συστήματα. Δυστυχώς, λόγω του οτι λειτουργεί με tokens και όχι με actual username/password/domain, δεν είναι τόσο απλή η υλοποίησή της και στο Web όλος ο κόσμος τσακώνεται για το πως θα λειτουργήσει σωστά...

    Το ζητούμενο

    Χρειάζομαι ολοκληρωμένο κώδικα ο οποίος θα λειτουργεί ΚΑΙ σε NT 4.0 Workstation και ο οποίος θα σηκώνει μια εξωτερική εφαρμογή ως χρήστης της επιλογής μου. Δεν με ενοχλεί να περνάει το password ή οχι, ως θέμα security, σε αυτό το σημείο. Ξερω οτι είναι αρκετά "βαρύ" το θέμα, οπότε απλα εύχομαι κάποιος φίλος να έχει ήδη "περάσει" αυτή τη φουρτούνα και να έχει κάτι να προτείνει.

    Παρακάτω παραθέτω τον κώδικα που χρησιμοποιεί την CreateProcessWithLogonW και ο οποίος δούλεψε μια χαρά σε Windows 2003 server (αλλα φυσικά όχι σε ΝΤ):

    Imports System
    Imports System.Drawing
    Imports System.Collections
    Imports System.ComponentModel
    Imports System.Windows.Forms
    Imports System.Data
    Imports System.Runtime.InteropServices
    Imports System.IO

    Public Class clsSpawnProcess

        <Flags()> _
        Enum LogonFlags
            LOGON_WITH_PROFILE = &H1
            LOGON_NETCREDENTIALS_ONLY = &H2
        End Enum

        <Flags()> _
        Enum CreationFlags

            CREATE_SUSPENDED = &H4
            CREATE_NEW_CONSOLE = &H10
            CREATE_NEW_PROCESS_GROUP = &H200
            CREATE_UNICODE_ENVIRONMENT = &H400
            CREATE_SEPARATE_WOW_VDM = &H800
            CREATE_DEFAULT_ERROR_MODE = &H4000000
        End Enum

        <StructLayout(LayoutKind.Sequential)> _
        Structure ProcessInfo
            Public hProcess As IntPtr
            Public hThread As IntPtr
            Public dwProcessId As UInt32
            Public dwThreadId As UInt32
        End Structure

        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
        Structure StartupInfo
            Public cb As Int32
            Public reserved1 As String
            Public desktop As String
            Public title As String
            Public dwX As UInt32
            Public dwY As UInt32
            Public dwXSize As UInt32
            Public dwYSize As UInt32
            Public dwXCountChars As UInt32
            Public dwYCountChars As UInt32
            Public dwFillAttribute As UInt32
            Public dwFlags As UInt32
            Public wShowWindow As Short
            Public reserved2 As Short
            Public reserved3 As Integer
            Public hStdInput As IntPtr
            Public hStdOutput As IntPtr
            Public hStdError As IntPtr
        End Structure

        <DllImport("advapi32.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True, SetLastError:=True)> _
        Public Shared Function CreateProcessWithLogonW( _
        ByVal principal As String, _
        ByVal authority As String, _
        ByVal password As String, _
        ByVal logonFlags As LogonFlags, _
        ByVal appName As String, _
        ByVal cmdLine As String, _
        ByVal creationFlags As CreationFlags, _
        ByVal environmentBlock As IntPtr, _
        ByVal currentDirectory As String, _
         ByRef startupInfo As StartupInfo, _
         ByRef processInfo As ProcessInfo) As Boolean
        End Function

        <DllImport("kernel32.dll")> _
        Public Shared Function CloseHandle(ByVal h As IntPtr) As Boolean
        End Function

        Public Shared Function CreateProcess( _
        ByVal username As String _
        , ByVal domain As String _
        , ByVal password As String _
        , ByVal applicationPath As String _
        , ByVal commandLineArgs As String)

            Dim si As StartupInfo = New StartupInfo
            si.cb = Marshal.SizeOf(GetType(StartupInfo))
            Dim pi As ProcessInfo = New ProcessInfo

            If (CreateProcessWithLogonW(username, domain, password, _
             LogonFlags.LOGON_WITH_PROFILE, _
             applicationPath, commandLineArgs, _
             0, IntPtr.Zero, Nothing, _
             si, pi)) Then
                CloseHandle(pi.hProcess)
                CloseHandle(pi.hThread)
            Else
                'TODO: throw exception here or something
                Console.WriteLine("Error code: {0}", Marshal.GetLastWin32Error())
            End If
        End Function
    End Class

    Τα φώτα σας!

     

     

     


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  09-12-2005, 14:36 7740 σε απάντηση της 7734

    Απ: Κλήση εξωτερικής εφαρμογής ως διαφορετικός user (.NET 1.1, API call)

    Γιατί δεν καλείς την LogonUser όπως λέει το SDK για να πάρεις Token και να το τρέξεις έτσι?
    Εγώ πάντως έτσι το κάνω..
    Ρώτησα και ένα φίλο μου που γράφει το InstallAware (τον installer αν τον ξέρετε) και μου είπε ακρίβως το ίδιο πράγμα..Παίρνεις τοκεν και καλείς την CreateProcessAsUser..
    Επίσης διαφώτισε με λίγο γιατι δεν είναι εύκολη η υλοιποίησή της..Μάλλον μου ξεφεύγει κάτι..
    Παναγιώτης Κεφαλίδης

    "Για να επιτύχεις, θα πρέπει το πάθος σου για την επιτυχία να είναι μεγαλύτερο απο τον φόβο σου για την αποτυχία"

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Παρακαλώ διαβάστε τους όρους χρήσης.
  •  09-12-2005, 14:44 7741 σε απάντηση της 7740

    Απ: Κλήση εξωτερικής εφαρμογής ως διαφορετικός user (.NET 1.1, API call)

    Θα το κοιτάξω οπως μου το λές. Η υλοποιηση της μπορεί να είναι εύκολη, εγώ όμως δηλώνω ημι-ασχετος απο api calls, οπότε...:)

    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  09-12-2005, 14:45 7742 σε απάντηση της 7740

    Απ: Κλήση εξωτερικής εφαρμογής ως διαφορετικός user (.NET 1.1, API call)

    Οτι θές ποστ.. δηλώνω κατι παραπάνω απο σχετικός, οπότε.. :D
    Παναγιώτης Κεφαλίδης

    "Για να επιτύχεις, θα πρέπει το πάθος σου για την επιτυχία να είναι μεγαλύτερο απο τον φόβο σου για την αποτυχία"

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Παρακαλώ διαβάστε τους όρους χρήσης.
  •  09-12-2005, 19:09 7750 σε απάντηση της 7742

    Απ: Κλήση εξωτερικής εφαρμογής ως διαφορετικός user (.NET 1.1, API call)

    Λοιπόν, τελικά πολύ αργά σήμερα έμαθα οτι το θέμα των NT4 είναι νεφελώδες. Ητοι αυτή τη στιγμή μου αρκεί ο κώδικας που έκανα ήδη post και ο οποίος δουλεύει. Ευχαριστώ πάντως τον pkefal (καθώς και τους gcapnias, pkanavos που τους έπρηξα στο MSN) για τα καθοδηγητικά τους σχόλια, θα κλείσω αυτό το θέμα εδώ και θα ...επανέλθω μόλις με ...αναγκάσουν :) :) :)

    Σχετικά τώρα με τη LogonUser, ταλαιπωρήθηκα λίγο. Εβγαζε errors η κλήση μου, δεν καταλάβαινα γιατί...(1412 ΕRROR_CONTROL_ID_NOT_FOUND στη συγκεκριμένη περίπτωση, που το έπαιρνα με το lastDLLError αφού είχε σκάσει unhandled exception). Ομως, θα πρότεινα να μην σας ταλαιπωρήσω άλλο με αυτό αφού προς το παρόν μπαίνει στο "ψυγείο". Και πάλι ευχαριστώ θερμά!

    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  09-12-2005, 22:41 7755 σε απάντηση της 7734

    Απ: Κλήση εξωτερικής εφαρμογής ως διαφορετικός user (.NET 1.1, API call)

    Έχει πολλές λόξες το .net όταν καλείς API.
    Πχ σε περιπτώσεις που βλέπεις ότι πρέπει να δώσεις απλά int για parameter στο call, διαπιστώνεις τελικά ότι έπρεπε να δώσεις UInt16 σαν parameter και όχι Int (ενώ φυσικά δεν αναφέρετε ΠΟΥΘΕΝΑ, αλλα θα έπρεπε να το φανταστείς καθώς το API ή και το structure είναι compatible με Win95.(Ο νοών νοήτο (βλέπε SYSTEMTIME stucture)) :D
    Πάντως θα ήθελα να σας κάνω add στο msn μου κι εγω(u, gcapnias κλπ)..Αν θέλετε στείλτε μου μαιλ στο pkef@-(nospam)-datafire-(nospam)-.gr με τα δικά σας μαιλ..
    Ciaoz
    Παναγιώτης Κεφαλίδης

    "Για να επιτύχεις, θα πρέπει το πάθος σου για την επιτυχία να είναι μεγαλύτερο απο τον φόβο σου για την αποτυχία"

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Παρακαλώ διαβάστε τους όρους χρήσης.
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems