Laden...

Exchange-Useraccounts per WindowsService auslesen

Erstellt von Noodles vor 18 Jahren Letzter Beitrag vor 18 Jahren 14.921 Views
N
Noodles Themenstarter:in
4.644 Beiträge seit 2004
vor 18 Jahren
Exchange-Useraccounts per WindowsService auslesen

Hi,

ich lese zur Zeit die Kontakte eines User per WebDAV aus dem Exchange aus. Soweit kein Problem ( mehr 😉 ). Nun möchte ich, dass ein WindowsService welcher unter einem eigenen Account läuft, diese Daten ausliest. Der Dienst bekommt aber nur den Namen des Users, nicht das Passwort.
Ist das überhaupt möglich, da mir ja das Passwort "fehlt" und wenn ja wie is der Ansatz.

Momentan:

string url = "http://<server>/Exchange/<user>/Kontakte";
ADODB.Connection conn = new ADODB.Connection();
conn.Provider = "exoledb.datasource";

conn.Open(url, "<user>", "<passw>", 0);

ADODB.RecordClass rec = new ADODB.RecordClass();
ADODB.RecordsetClass rs = new ADODB.RecordsetClass();

rec.Open(url, conn, ADODB.ConnectModeEnum.adModeReadWrite, ADODB.RecordCreateOptionsEnum.adFailIfNotExists,
ADODB.RecordOpenOptionsEnum.adOpenRecordUnspecified, "<user>", "<passw>");

string query = "";
	
rs.Open(query, rec.get_ActiveConnection(), ADODB.CursorTypeEnum.adOpenForwardOnly,
ADODB.LockTypeEnum.adLockOptimistic, (int)ADODB.CommandTypeEnum.adCmdUnspecified);

while (!rs.EOF)
    // Daten lesen

Das ist der Ansatz wie man die Kontakte eines Users ausliest. Allerdings muss man auch in dessen Account eingeloggt sein.

I
1.739 Beiträge seit 2005
vor 18 Jahren

Ohne Übergabe des Passwortes ist nichts zu machen. Wäre es anders wär das schon in allen News gewesen(peinliches Sicherheitsloch).

N
Noodles Themenstarter:in
4.644 Beiträge seit 2004
vor 18 Jahren

Wie machen das dann igrendwelche Backup-Dienste usw.? Die müssen doch da auch rankommen, oder?

I
1.739 Beiträge seit 2005
vor 18 Jahren

>Wie machen das dann igrendwelche Backup-Dienste usw.? Die müssen doch da auch rankommen, oder?

Es gibt unterschiedliche Lösungsansätze. Entweder ist dein Dienst selbst ein Nutzer (mit höheren Rechten zum Auslesen aller Accounts). Oder er verwaltet UserDaten(nicht so Ideal bei Passwortänderungen).
Problematisch ist die Datenhaltung der Accountdaten(Verschlüsselung). Da du mit .Net 2.0 arbeitest hast du es mit Securestring ein bisschen leichter.
Es gibt noch mehr Möglichkeiten, die sind dann abhängig vom was und wie.
Frage:
Liest der Dienst die Daten "von allein" oder auf Anforderung(per Remoting oder so)?

N
Noodles Themenstarter:in
4.644 Beiträge seit 2004
vor 18 Jahren

Der Dienst soll die Daten von allein lesen. Weiterhin ist er auch von mir konfigurierbar ( was die Rechte angeht ). Sagen wir mal der Dienst hat höhere Rechte. Wie komme ich dann an die anderen Accounts ran. Wenn ich connecten will, bekomme ich nur COMExceptions wegen Authentifizierungproblemen.

I
1.739 Beiträge seit 2005
vor 18 Jahren

>Sagen wir mal der Dienst hat höhere Rechte. Wie komme ich dann an die >anderen Accounts ran.
Ist das eine spezifische Frage zum Exchangeserver? Wenn ja, kann ich dir leider nicht weiterhelfen(nicht mein Gebiet).
Falls nein, ich meinte dein Dienst(als User des Exchangeservers) besitzt die Rechte zum Auslesen der Daten anderer Accounts, oder er muss sich als jeweiliger Nutzer ausgeben(und deren Zugangsdaten besitzen).
>Wenn ich connecten will, bekomme ich nur COMExceptions wegen >Authentifizierungproblemen.
Mit Passwort oder ohne?

N
Noodles Themenstarter:in
4.644 Beiträge seit 2004
vor 18 Jahren

Original von ikaros
Falls nein, ich meinte dein Dienst(als User des Exchangeservers) besitzt die Rechte zum Auslesen der Daten anderer Accounts, oder er muss sich als jeweiliger Nutzer ausgeben(und deren Zugangsdaten besitzen).

Ich teste es momentan mit einem normalen User, der aber die höchsten Rechte im Exchange hat. Es funktioniert trotzdem noch nicht.

Original von ikaros
Mit Passwort oder ohne?

Ich bin als User X im Windows eingeloggt. Nun möchte ich auf den Exchange Account von User Y zugreifen, dessen Username und Passwort ich habe. Ich komme aber nicht rein -> COMException. Das ganz soll aber eigentlich wie gesagt nur mit dem Usernamen funktionieren, also ohne Passwort.

I
1.739 Beiträge seit 2005
vor 18 Jahren

Wie gesagt ohne Passwort als User y wird nicht funktionieren. Tut mir leid, dass ich nicht weiterhelfen kann. Ich wünsch dir viel Erfolg.
Wenn du deine Lösung fertig hast kannst du sie ja mal posten oder ein kleines Tut schreiben. Sieht so aus als ob das Thema einge interessiert(Ich hab ein bisschen gegoogelt).

4.221 Beiträge seit 2005
vor 18 Jahren

Hast Du schon mit WindowsIdentity.Impersonate rumgespielt (siehe Samples hierzu im SDK)... ev. kannst Du ja vorgaukeln Y zu sein (aber vermutlich auch nur wenn Du das Passwort hast ....)

PS: Ich hab selber dahingehend keine Erfahrungen....

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

3.728 Beiträge seit 2005
vor 18 Jahren
Datensicherung

Sicherungsprogramme haben das Problem nicht, da Exchange eine spezielle API für Backup-Software zur verfügung stellt. Damit kann man aber nicht auf Inhalte der Postfächer zugreifen sondern nur komplette postfächer oder komplette Infomrationsspeicher wegsichern.

Nach deutschem Recht ist das "Privates Postfach für jeden Mitarbeiter"-Modell von Outlook und Exchange Server für Firmen kompletter Schwachsinn. Das mag für amerikanische Bedürfnisse passen und ist für privat super. Eigentlich müssten die E-Mails in Ordnern gesammelt werden, auf die mehrere Benutzer zugreifen können. Mails mit privatem Inhalt müssten mit einem Privat- bzw. Vertraulich-Attribut versehen und verschlüsselt werden, um dem Datenschutz gerecht zu werden. Dann gäbe es viel weniger Probleme, wenn Mitarbeiter im Urlaub oder krank sind. Außerdem könnten Mails leicher Klassifiziert und mit CRM-System verknüpft werden. Alle Bestellungen, die per Mail eingegangen sind, wären auf einfache Weise für die zuständigen Sachbearbeiter verfügbar (Nur ein Beispiel). Es hätte ja trotzdem jeder Mitarbeiter seine eigene E-Mail-Adresse.

Eine Möglichkeit, dem Postfachzugriffsproblem zu entkommen ist, mailaktivierte öffentliche Ordner zu verwenden und den Benutzern SendAs-Berechtigungen darauf zu erteilen. Um das aber sinnvoll nutzen zu können, müsste man Outlook entsagen und einen MAPI-Client nach eigenen Bedürfnuissen schreiben.

3.728 Beiträge seit 2005
vor 18 Jahren
Lösung

Mit folgendem Code (CDO 1.21) kannst Du auf das Postfach eines anderen Benutzers zugreifen, wenn Du die Rechte dazu hast (Das Benutzerkonto des Dienstes muss natürlich über eine Exchange-Mailbox verfügen!):


// MAPI-Sitzung erzeugen
MAPI.Session session=new MAPI.SessionClass();

// Konfiguration für temporäres MAPI-Profil festlegen 
// Servername ist der Name des Exchange-Servers
// Username ist der Name des Postfachs (Normalerweise = ActiveDirectory-Benutzername)
string profile="Servername" + "\\n" + "Username"; 

// Mit temporären MAPI-Profil anmelden
session.Logon(Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,profile);

// Kontaktordner des Benutzers abrufen
MAPI.Folder contactFolder=(MAPI.Folder)session.GetDefaultFolder(MAPI.CdoDefaultFolderTypes.CdoDefaultFolderContacts);

// Kontakte aus dem Ordner abrufen
MAPI.Messages contacts=(MAPI.Messages)contactFolder.Messages;

Du musst den COM-Verweis "Microsoft CDO 1.21" einbinden. Die Lösung selbst liegt in der Verwendung eines temporären MAPI-Profils. Über contacts kommst Du an die einzelnen Kontakte.

N
Noodles Themenstarter:in
4.644 Beiträge seit 2004
vor 18 Jahren

Hallo Rainbird,

danke für das Beispiel. Ich kann jetzt auf die verschiedenen Accounts zugreifen. Allerdings muss jedem dieser Accounts bei den Postfachberechtigungen, der ServiceAccount hinzugefügt werden. Kann man das umgehen?
Wie bekomme ich denn noch die Adresse des Kontaktes? Ich habe den Namen und das LastModifiedDate usw., aber die Adresse finde ich nicht.

Edit:
Warum benutzt man nicht CDOEXM ( Microsoft CDO for Exchange Management Library ) oder CDO ( Microsoft CDO For Exchange 2000 Library )?

3.728 Beiträge seit 2005
vor 18 Jahren

Hallo Noodles,

bei MAPI (CDO) ist alles immer eine MAPI.Message (Ob das eine E-Mail, eine Aufgabe, ein Kontakt oder sonstwas ist, spielt keine Rolle). Alles was über eine Standardnachricht hinausgeht wird in zusätzlichen Feldern gespeichert (Fields-Auflistung der Message). Diese Fields werden über einen sogenannten "PropertyTag" angesprochen. Das ist ein Hex-Wert, der das Feld eindeutig identifiziert. Im MAPI-Namensraum gibt es einen Enum mit den gängigsten. Viele Eigenschaften sind dort aber gar nicht aufgeführt. Ich empfehle da lieber das Tool OutlookSpy. Damit kommt man z.B. auf an Outlook 2003 spezifische PropertyTags. Ich hab das mal gebraucht, um die bunten Nachverfolgungsfähnchen automatisch zu setzen.

http://www.dimastr.com/outspy/

CDO 1.21 erschien mir auf Anhieb sinnvoll aufgebaut zu sein. Dort gibt es Objekte für die Dinge, die man als Exchange Admin kennt (Informationsspeicher, Postfächer, Ordner, Nachrichten, Felder, Eigenschaften). Diese anderen "modernen" APIs adressieren teilweise mit XML-Schemas. Die URNs sind höllisch lang und verschachtelt. Ich hab auch keine Übersicht gefunden, welches Schema welche Objekte darstellt. Im Web gibts auch keine sinnvollen Beispiele (Bitte um korrektur, sollte ich was übersehen haben). Außerdem war mir nicht klar ob es sich um eigene Exchange spezifische Schemas handelt oder ob es die Erweiterten Active Directory Schemaklassen sind (Exchange Server 2000 und 2003 registrieren eigene Schemaerweiterungen im Active Directory Schema).

Ich mag Dinge die einfach funktionieren (Sonst würde ich kein Windows benutzen).

N
Noodles Themenstarter:in
4.644 Beiträge seit 2004
vor 18 Jahren

OK, ich habe auch eine Variante mit WebDAV und die ist schon ein ganzes Stück länger wie die mit CDO.
Wie erhalte ich denn nun die Adresse, habe sie immer noch nicht gefunden ( da ich die WebDAV Variante zur zeit nutze )?
Ich möchte auch zu jedem Contact benutzerdefinierte Daten speichern, ist dies mit CDO möglich? Momentan versuche ich das Schema zu erweitern, aber vielleicht gibt es ja auch einen einfacheren Weg.

N
Noodles Themenstarter:in
4.644 Beiträge seit 2004
vor 18 Jahren

OK, WebDav ist dann wohl nicht mehr der richtige Weg. Denn wie ich gerade erfahren habe, soll dies in der nächsten Exchange Version durch WebServices ersetzt werden.

3.728 Beiträge seit 2005
vor 18 Jahren
Fields / Properties

Du kannst bei CDO eigene Fields anlegen. Das geht auch in Outlook. Diese können per Nachricht oder per Ordner verfügbar sein. Wenn Du sie für Gruppierung oder Filter verwenden willst, müssen sie im ordner verfügbar gemacht werden. Diese Fields (z.B. auch die Adresse (Straße, PLZ etc.) eines Kontaktes bekommst Du über diese Fields-Auflistung der Message (des Kontakts). Messages adressiert man ähnlich wie bei Outlook über die eindeutige ID (EntryID) und die eindeutige ID des Informationsspeichers (StoreID).

Folgende Seite hat viele Tipps zu CDO, Outlook und Exchange: http://www.cdolive.com/cdo10.htm
Dort wird auch beschrieben, wie man eigene Felder anlegt.

Hier die Property Tags für die Adresse:

0x8046 = Adresse (Fließtext)
0x8069 = Ort
0x806B = Postleitzahl
0x806D = Straße

oder

MAPI.CdoPropTags.CdoPR_POSTAL_ADDRESS

N
Noodles Themenstarter:in
4.644 Beiträge seit 2004
vor 18 Jahren

Hi,

danke für die Antwort. Ich habe ich jetzt für folgende Varainte entschieden, die auch fast 100%-ig funktioniert.

CDO.Person person = new CDO.Person();
person.FirstName = myPerson.FirstName;
person.LastName = myPerson.LastName;
person.Email = //...

person.DataSource.SaveToContainer(url, null, ADODB.ConnectModeEnum.adModeReadWrite, ADODB.RecordCreateOptionsEnum.adCreateNonCollection, ADODB.RecordOpenOptionsEnum.adOpenSource, "", "");

person = null;

Ich möchte allerdings noch etwas im "urn:schemas-microsoft-com:office:office#Keywords" speichern. Allerdings komme ich so nicht an das Feld heran. Weißt Du wie ich das schreiben kann. Wenn Du im Outlook zu einem Kontakt eine Kategorie speicherst, wird diese da eingetragen, ich möchte da programmatisch was reinschreiben.

N
Noodles Themenstarter:in
4.644 Beiträge seit 2004
vor 18 Jahren

Ok, erledigt man muss ein Array zuweisen.

fields["urn:schemas-microsoft-com:office:office#Keywords"].Value = new object[] { "..." };

Vielen Dank nochmal an alle.

S
44 Beiträge seit 2005
vor 18 Jahren

hi, kann das auch für diese seite laufen?
https://www.cti.ac.at/exchange

das wär dann genial😉
cu

3.728 Beiträge seit 2005
vor 18 Jahren
Outlook Web Access

Die genannte Seite verweist auf ein Outlook Web Access. Das ist nur ein Client von Exchange, wie z.B. Outlook 2003. Outlook Web Access ist in ASP (Exchange 5.5-Exchange 2000) oder in ASP.NET (Exchange 2003) geschrieben. In ASP.NET Webforms oder normalen ASP-Seiten kannst Du natürlich auch CDO verwenden, um auf Exchange Server zuzugreifen. Es sind auch Programme möglich, die auf einem Server laufen (z.B. als Windows-Dienst) und mit CDO bestimmte Postfächer oder Ordner überwachen und irgendetwas ausführen. Auch VB6 oder VBScript Programme können CDO verwenden, da es eine COM-Komponente ist. Du kannst es auch in Office-Markros einbauen. Und, und, und.

S
44 Beiträge seit 2005
vor 18 Jahren

kann ich mich dann so einloggen:


string url = "https://www.cti.ac.at/exchange/";
ADODB.Connection conn = new ADODB.Connection();
conn.Provider = "exoledb.datasource";
conn.Open(url, "xxxx", "xxxx", 0);

wenn ich mich einlogge bekomme ich eine var g_szSessionId...
der server verwendet ASP.NET und arbeitet mit java scripts...
macht die verschlüsselung kein problem?

cu

3.728 Beiträge seit 2005
vor 18 Jahren
Client

Wenn ich Dich richtig verstanden habe, willst Du vom Internet aus übers Outlook Web Access den Exchange Server programmieren (Korrigier mich bitte, falls ich was falsch verstanden habe).

Das klappt so nicht. Mit Deinem URL landest Du beim Outlook Web Access und nicht beim Exchange Server. Du brauchst für CDO eine direkte Verbindung zum Exchange Server. Der Webserver hat ja nichts mit dem Exchange Server zu tun. Er führt nur die ASP.NET Seiten von Outlook Web Access aus.

S
44 Beiträge seit 2005
vor 18 Jahren

hi, programmiern will ich den server nicht, sondern nur connecten und emails abrufen!! wie find ich die direkte Verbindung zum Exchange Server raus?

cu

3.728 Beiträge seit 2005
vor 18 Jahren
Outlook

Standardmäßig werden Outlook Web Access und Exchange Server auf der selben Maschine ausgeführt. Bei größeren Installationen kann Outlook Web Access aber auch auf einem separaten Webserver-PC liegen. Exchange Clients wie Outlook oder Programme die CDO verwenden, kommunizieren mit dem Exchange Server über RPC (Remote Procedure Call). Dazu wird TCP Port 135 auf dem Exchange Server Computer verwendet. Dieser Port sollte aber nicht über das Internet zugreifbar sein, weil er anfällig für Hackerattacken ist. Deshalb wird auch keine CDO-Verbindung zum Exchange Server über das Internet klappen. Mit 99%iger Sicherheit ist das Unternehmensnetzwerk durch eine Firewall geschützt (Wenn nicht, sollte man den Admin feuern und jemand mit mehr Sachverstand einstellen).
Seit Exchange Server 2000 gibt es die Möglichkeit auch über eine gesicherte HTTP-Verbindung mit Outlook zuzugreifen. Ich verwende selbst diese Einstellung in meinem privaten Outlook, um auf den Exchange Server von 1&1 zuzugreifen (Siehe Screenshot im Anhang). Outlook 2003 unterstützt diese Verbindungsmethode. Ob man das auch mit CDO nutzen kann, weiß ich nicht. Da müsstest Du unter msdn.microsoft.com und www.technet.com recherchieren. Irgendwie bestimmt, denn Outlook machts ja auch.

Normalerweise wird CDO im LAN eingesetzt. Dort ist auch der Zugriff auf den Port 135 kein Problem.

Der folgende Artikel aus der Microsoft Knowledge Base beschreibt die verschiedenen Verbindungsmöglichkeiten zum Exchange Server:

http://support.microsoft.com/kb/q176466/

Wenn Du aber nur Deine E-Mails abrufen willst, dann verwende doch einen IMAP4 oder POP3 Client. Diese Ports sollten normalerweise offen sein. Es sei denn die Frima möchte die Exchange-Dienste nur über Outlook Web Access zur Verfügung stellen.