Zugriff ASP.NET Server auf Navision Datenbank

31. März 2009 14:40

Hallo zusammen,

ich habe ein kleines Problem. Ich habe unter ASP.NET eine Seite geschrieben, welche über die WebServices auf Navision zugreift.

Wenn der ASP.NET-Server und die Navision-Datenbank auf dem selben Rechner liegen funktioniert das Ganze problemlos. Von jedem Rechner
kann ich die Seite über den ASP.NET-Server aufrufen und habe darüber Zugriff auf die Datenbank.

Nun liegt der ASP.NET-Server und die Datenbank auf verschiedenen Rechnern. Jetzt habe ich das Problem, dass der ASP.NET-Server nicht mehr
mit der Datenbank kommunizieren kann, da das Ganze schätzungsweise ausschließlich über Windows-Anmeldungen funktioniert und ich keine
Domäne habe.

Kann man das Problem irgendwie umgehen?

Vielen Dank im Voraus.

Re: Zugriff ASP.NET Server auf Navision Datenbank

1. April 2009 09:08

Das Stichwort heißt Impersonifizierung. Im Prinzip übergibst Du an den Webserver einen NAV-berechtigten User. Schau mal bei MSDN hierzu.

Volker

Re: Zugriff ASP.NET Server auf Navision Datenbank

1. April 2009 11:56

Hallo,

danke für die Antwort.

Hast du evtl. irgendein Beispiel für mich? Die Anleitungen im msdn sind doch etwas undurchsichtig ...

Re: Zugriff ASP.NET Server auf Navision Datenbank

1. April 2009 13:45

Unten stehendes in Deine aspx-Seite sollte in etwa funktionieren (C#, aber sollte nicht so schwer nach VB zu bringen sein):

Code:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

using System.Runtime.InteropServices;
using System.Text;

namespace ImpAuth
{
   public class WebForm1 : System.Web.UI.Page
   {
      const int LOGON32_LOGON_INTERACTIVE       = 2;
      const int LOGON32_LOGON_NETWORK           = 3;
      const int LOGON32_LOGON_BATCH             = 4;
      const int LOGON32_LOGON_SERVICE           = 5;
      const int LOGON32_LOGON_UNLOCK            = 7;
      const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
      const int LOGON32_LOGON_NEW_CREDENTIALS   = 9;
      const int LOGON32_PROVIDER_DEFAULT        = 0;

      [DllImport("advapi32.dll", SetLastError=true)]
      public static extern int LogonUser(
         string lpszUsername,
         string lpszDomain,
         string lpszPassword,
         int dwLogonType,
         int dwLogonProvider,
         out IntPtr phToken
         );
      [DllImport("advapi32.dll", SetLastError=true)]
      public static extern int ImpersonateLoggedOnUser(
         IntPtr hToken
         );

      [DllImport("advapi32.dll", SetLastError=true)]
      static extern int RevertToSelf();

      [DllImport("kernel32.dll", SetLastError=true)]
      static extern int CloseHandle(IntPtr hObject);

      private void Page_Load(object sender, System.EventArgs e)
      {
         Response.Write("Now logged on: " +
            Environment.UserName + "<hr/>");

         IntPtr lnToken;
         int TResult = LogonUser("Administrator",".","reBellion$",               
            LOGON32_LOGON_NETWORK,LOGON32_PROVIDER_DEFAULT,               
            out lnToken);

         if ( TResult > 0 )
         {
            ImpersonateLoggedOnUser(lnToken);
            
            /*Code der unter anderem benutzer ausgeführt werden soll*/

            RevertToSelf();
            CloseHandle(lnToken);
         }

      }

      #region Web Form Designer generated code
      override protected void OnInit(EventArgs e)
      {
         //
         // CODEGEN: This call is required by the ASP.NET Web Form Designer.
         //
         InitializeComponent();
         base.OnInit(e);
      }
      
      /// <summary>
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// </summary>
      private void InitializeComponent()
      {   
         this.Load += new System.EventHandler(this.Page_Load);
      }
      #endregion
   }
}


Volker

Re: Zugriff ASP.NET Server auf Navision Datenbank

1. April 2009 15:38

C# ist schon Ok :-)

Werd's mal testen. Danke schonmal.

Re: Zugriff ASP.NET Server auf Navision Datenbank

7. April 2009 13:19

Hallo nochmal,

irgendwie krieg ich das nicht zum Laufen ... nochmal zum Verständnis:

der ASP.NET Server läuft auf einem anderen Rechner - ich habe keine Domäne.


ASP.NET Server


|
| - anderen User einloggen -
v


Navision-Datenbank


Und mit diesem Code kann ich dem Code den Windows-User eines anderen Rechners übergeben, obwohl dieser den garnicht kennt??!

Re: Zugriff ASP.NET Server auf Navision Datenbank

7. April 2009 13:47

Dein ASP.NET Server (IIS) läuft unter einem Account z. B. WPG. Standarmäßig versucht der jetzt der ASP.NET Server mit diesem User auf Deine DB zuzugreifen. Allerdings kennt Deine NAV-DB den User nicht. Du übergibst jetzt Deinem ASP.NET-Server einen in NAV angelegten Benutzer (z. B. sa). Diesen Benutzer verwendet jetzt Dein ASP.NET-Server um auf die NAV-DB zuzugreifen. Mit dem angemeldeten Windowsbenutzer hat das gar nix zu tun und kann nicht funktionieren, da diese auf dem anderen Rechner (keine Domäne) nicht bekannt ist. Den NAV-Benutzer (und Passwort) mußt Du schon manuell oder via Programmcode an den ASP.NET-Server übergeben.

Volker

Re: Zugriff ASP.NET Server auf Navision Datenbank

7. April 2009 14:06

Lokal funktioniert es mit dem "übergebenen User" ... sobald ich den ASP-Server von der Datenbank trenne geht es nicht.

Habe mittlerweile den kompletten, webservice bezogenen Code in die IF-Verzweigung (TResult > 0) ausgelagert.

Hast du noch eine Idee was ich falsch machen könnte?

Vielen Dank im Voraus.

Re: Zugriff ASP.NET Server auf Navision Datenbank

7. April 2009 14:31

Kannst Du denn den Webservice vom ASP.NET-Server überhaupt erreichen? z. b. im Webbrowser?

Re: Zugriff ASP.NET Server auf Navision Datenbank

7. April 2009 14:41

Ja, das funktioniert.

Muss ich meinem WebService noch irgendwie die geänderten "Credentials" zuweisen?

Momentan benutze ich "UseDefaultCredentials".

Re: Zugriff ASP.NET Server auf Navision Datenbank

7. April 2009 18:04

Kann es sein, dass Du in Deiner ASP-Seite nicht auf die richtige URL für den Webservice verweisst, sondern immer noch die lokale URL drin hast?

Re: Zugriff ASP.NET Server auf Navision Datenbank

7. April 2009 18:23

Ne, hab die Webreferenz dynamisch und den richtigen Link in der Web-Config eingestellt.

Die URL des WebService ist auch korrekt.

Re: Zugriff ASP.NET Server auf Navision Datenbank

9. April 2009 08:12

Keine Idee mehr? :-(

Ich habe irgendwo gelesen, dass man in einer XML Config den Key "impersonate" setzen muss.
Oder muss ich vielleicht noch im ASP Server selbst etwas einstellen?

Hat es evtl. damit etwas zu tun?

Re: Zugriff ASP.NET Server auf Navision Datenbank

12. Mai 2009 15:33

hast du jetzt nur das problem, dass du aus deinem asp.net projekt nicht auf die navision datenbank zugreifen kannst oder gibt es noch ein problem mit dem webservice?

für ersteres ist doch allein der connectionstring der SqlConnection zuständig, oder? also auf die schnelle hast du zum beispiel sowas in der art:
Code:
public static class DbAccess
{       
        private static SqlConnection sqlCon;
       
        public static DataTable executeQuery(string query)
        {
            try
            {       
                if (sqlCon == null)
                    sqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["sqlConnect"].ConnectionString);

                if (!(sqlCon.State == ConnectionState.Open))
                    sqlCon.Open();

                SqlCommand sqlCom = new SqlCommand(query, sqlCon);
                SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCom);
                DataSet ds = new DataSet();
                sqlDa.Fill(ds);
                sqlCon.Close();

                return ds.Tables[0];
            }
            catch (Exception) { sqlCon.Close(); }
        }
}


in der web.config definiert du dann einen abschnitt mit dem gültigen connectionstring, also etwa in der art
Code:
[...]
<connectionStrings>
    <add name="sqlConnect" connectionString="Data Source=[hier den namen des sql-servers];Initial Catalog=[hier den namen der datenbank];User ID=[hier den namen des benutzers];Password=[hier das passwort]"/>
</connectionStrings>
[...]


zum testen kann man den string auch hardcodiert in die obige klasse packen. der benutzer muss natürlich im sql-server vorhanden sein. jetzt kann man an beliebiger stelle sich ein query zusammen bauen und DbAccess.executeQuery(querystring) aufrufen.