Laden...

Wie kann ich eine externe Konfigurationsdatei in meine app.config einbinden?

Erstellt von xKushGene vor 6 Jahren Letzter Beitrag vor 6 Jahren 4.303 Views
X
xKushGene Themenstarter:in
91 Beiträge seit 2017
vor 6 Jahren
Wie kann ich eine externe Konfigurationsdatei in meine app.config einbinden?

Ich lese mir aktuell folgendes durch, um meine app.config zu sichern bzw. nur die Verbindungsdaten zu meiner Datenbank:

https://msdn.microsoft.com/de-de/library/ms254494(v=vs.110).aspx#Arbeiten mit Anwendungskonfigurationsdateien

Dort steht geschrieben, dass ich eine externe Konfigurationsdatei anlegen kann und diese dann in meine app.config einbinden kann:

connections.config


<?xml version="1.0" encoding="utf-8" ?>
<connectionStrings>
  <add name="myConnectionString"
       providerName="MySql.Data.MySqlClient;"
       connectionString="Server=MEINHOST.de;Database=myDataBase;Uid=root;Pwd=myPass;"/>
</connectionStrings>

Und in meiner app.config so verlinkt:


<configuration>
    <connectionStrings configSource="connections.config" />
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="ControlcenterWPF.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
    <userSettings>
        <ControlcenterWPF.Properties.Settings>
            <setting name="Username" serializeAs="String">
                <value />
            </setting>
            <setting name="Password" serializeAs="String">
                <value />
            </setting>
            <setting name="StayLoggedIn" serializeAs="String">
                <value />
            </setting>
            <setting name="mysql_server" serializeAs="String">
                <value />
            </setting>
            <setting name="mysql_user" serializeAs="String">
                <value />
            </setting>
            <setting name="mysql_password" serializeAs="String">
                <value />
            </setting>
            <setting name="mysql_database" serializeAs="String">
                <value />
            </setting>
            <setting name="firmenkundentabelle" serializeAs="String">
                <value />
            </setting>
        </ControlcenterWPF.Properties.Settings>
    </userSettings>
</configuration>

So sieht meine app.config aus wo ich allerdings auch nicht genau weiß, was die ersten Zeilen bedeuten und sie daher einfach so lasse.

Auf jeden Fall bekomme ich nun jedes mal einen Error:> Fehlermeldung:

Ein Ausnahmefehler des Typs "System.TypeInitializationException" ist in PresentationFramework.dll aufgetreten.

Zusätzliche Informationen: Der Typeninitialisierer für "System.Windows.Application" hat eine Ausnahme verursacht.

Wenn ich

<connectionStrings configSource="connections.config" />

wieder entferne, bekomme ich den Error nicht.

Weiß hier jemand vlt. woran das liegt? Mein Ziel ist es am Ende einen verschlüsselten connectionString zu haben, da wie man an meiner aktuellen app.config sehen kann, ich den connectionString derzeit folgendermaßen zusammenbaue:


string con = string.Format("Server={0}; DATABASE={1}; UID={2}; PWD={3};", Settings.Default.mysql_server, Settings.Default.mysql_database, Settings.Default.mysql_user, Settings.Default.mysql_password);

Und das ziemlich unsicher ist ^^.

Ich benutze MySQL Connector/Net um eine Verbindung zu meiner Datenbank herzustellen. Weshalb ich bei ProviderName auch Mysql.Data.MysqlClient angegebene habe (sofern das denn auch richtig ist).

16.841 Beiträge seit 2008
vor 6 Jahren

Du tust Dich in diesem Fall einfacher, wenn Du die einzelnen Elemente des ConfigStrings einfach einzeln abspeicherst (zB. über AppKeys in der *.config) und dann im Quellcode mit dem ConnectionStringBuilder arbeitest.

X
xKushGene Themenstarter:in
91 Beiträge seit 2017
vor 6 Jahren

Also so wie ich es derzeit habe?
Ich habe ja mysql_server usw. aber diese sind eben nicht verschlüsselt und in %appdata% ganz leicht auslesbar. Das will ich ja vermeiden weshalb ich nun diesen connectionStrings verwendet möchte weil man den ja verschlüsseln kann.

Ich lese mich da aktuell noch durch, blicken tue ich das ganze noch nicht ganz.

Edit:
Ich hab es aktuell schon mal hinbekommen, dass ich mich verbinden kann. Aber ich kann connectionStrings immer noch nicht in connections.config auslagern.> Fehlermeldung:

Zusätzliche Informationen: Die configSource-Datei "connections.config" kann nicht geöffnet werden.

16.841 Beiträge seit 2008
vor 6 Jahren

Verschlüsseln ist bei Config Dateien sowieso nie 100% möglich.
Siehe auch [FAQ] DB-Password/Kennwort/Connection-String sicher speichern

Lass mich zunächst was anderes Fragen:
wieso verbinden sich die Benutzer direkt mit der Datenbank? Das macht man eigentlich aus eben Sicherheitsgründen normalerweise nicht mehr so. Das hat man früher mal so gemacht (leider).
Heute würde man einen entsprechenden Service dazwischen schalten, der Credentials zB. auf Token-Basis akzeptiert, um den Benutzer eindeutig identifizieren und ein Rechte- sowie Rollensystem überhaupt aufbauen zu können.

Gibt es einen Grund, wieso die Anwendung direkt mit der Datenbank kommuniziert, wenn es offensichtlich ein Mehrbenutzer-System ist?
Gefühlt ist das hier einfach nur Security through obscurity und nur eine Frage der Zeit, bis es jemand durchschaut.

X
xKushGene Themenstarter:in
91 Beiträge seit 2017
vor 6 Jahren

Ich bin wie schon mal woanders erwähnt derzeit in einer sehr schlechten Ausbildung und muss mir das meiste selber beibringen.

Dinge wie

Heute würde man einen entsprechenden Service dazwischen schalten, der Credentials zB. auf Token-Basis akzeptiert

sind mir eben neu.

Mein Rollensystem besteht zum Beispiel aus:


if(reader[4] == 0)
   return "Keine Rechte";
else if(reader[4] == 1)
   return "Er hat Rechte";

Also ich bin da noch nicht sonderlich professionell.

Das Ding ist, dass das Programm was ich schreibe auf eine Datenbank zugreift.
Da die Verbindung zu einer Datenbank immer anders sein kann, habe ich beim Login Fenster ein Popup Fenster eingebaut, wo man die MySQL Daten eingeben kann. Bei einem Klick auf speichern werden diese also in die app.config eingespeichert und das Programm wird neugestartet, damit die Änderungen auch wirksam gemacht werden.

Ich habe daher kein festen connectionString, da dieser eben von User zu User validieren kann.

Bisher hat die app.config ganz gut geklappt bis ich eben in %appdata% diese config Datei mit samt Inhalt gefunden habe und gesehen habe, dass die mysql Verbindungsdaten dort komplett unverschlüsselt ausgegeben werden.

Deswegen bin ich nun hier angelangt.

Die Frage ist jetzt. Wie kann ich den connectionString sicher machen, wenn es laut: DB-Passwort sicher speichern

gar nicht geht bzw. man immer noch die Daten herausfinden kann?

Den Link: https://msdn.microsoft.com/de-de/library/53tyfkaw(v=vs.110).aspx

habe ich mir schon vorgemerkt. Aber erst mal habe ich ja noch das Problem, dass ich connectionStrings nicht in connections.config auslagern kann wie hier beschrieben:
https://msdn.microsoft.com/de-de/library/ms254494(v=vs.110).aspx#Arbeiten mit Anwendungskonfigurationsdateien

16.841 Beiträge seit 2008
vor 6 Jahren

Dass Sachen neu sind, ist absolut nicht schlimm. Dafür lernt man ja.
Aber wenn Du Dinge nicht kennst, dann empfiehlt es sich zu informieren und evaluieren, was der beste/geeignetste Weg ist - und gerade beim Thema Sicherheit nicht irgendwas bastelt.
Vorarbeit ist sehr wichtig in der Software-Entwicklung. Ohne Konzeptphase arbeitet man oft doppelt.

Wenn Du die Datenbankdaten in einem Fenster beim Start annimmst, dann halte diese einfach im Speicher und verwende dann den ConnectionStringBuilder für den Aufbau, statt in die Config zu schreiben; das spart Dir auch den Neustart der Anwendung.

Wie gesagt, 100% sicher kannst Du es auf diesem Wege gar nicht machen; außer über ein völlig anderes Login-System mit einem dazwischen geschaltenen Service.
Sobald Du die Daten irgendwo lokal ablegst (Datei, Registry) kann man sie auslesen - man muss nur ein wenig Zeit investieren und schauen, wie Deine Anwendung funktioniert.

X
xKushGene Themenstarter:in
91 Beiträge seit 2017
vor 6 Jahren

Ich gebe die MysqlDaten ja nicht bei jedem Anwendungsstart ein. Deswegen werden diese in der app.config gespeichert.

Ich möchte das alles noch ändern, also sowas wie ein "First Start"-Fenster.
Das Konzept soll wie bei Wordpress sein. Man öffnet das erste mal die Anwendung, nun muss man die Verbindungsdaten zur MySQL Datenbank angeben und bei erfolgreicher Verbindung werden Tabellen und ein Admin Account erstellt.

Ich möchte ja ein Programm schreiben, indem man seine Kunden für einen Laden, einen Service oder so, verwalten zu können. Das heißt jeder Anwender benutzt eine andere Datenbank, wie bei wordpress eben. Da werden die Datenbank informationen ja auch auf dem installierten Webserver gespeichert.
So wie bei meinem Programm die MySQL Daten auf dem installierten PC gespeichert werden sollen.
Dann gibt es ja noch Fälle wie, "Chef gibt das Programm Praktikant XY um auch Kunden auf seine Datenbank einzutragen".
Das heißt, auch er muss auf die gleiche Datenbank zugreifen können, also kommt wieder das Fenster, wo man eine Verbindung zur Datenbank eingeben kann damit diese auch auf dem PC des Praktikanten gespeichert werden.

Ist der connectionString in der app.config also nicht NullOrEmpty, soll das Fenster zur Eingabe für die MySQL Daten auch nicht kommen. Allerdings kann es ja mal sein, dass man "umzieht" auf einen anderen Hoster und man andere MySQL Daten hat. Dafür soll es im programm dann eine Einstellung geben, diese MySQL Daten wieder zu ändern, also der Eintrag connectionString in der app.config soll überschrieben werden.

Natürlich muss das alles eben verschlüsselt sein. Und besser eine nicht perfekte und für einen erfahrenen Entwickler leicht knackbare Verschlüsselung, als roh-text in einer xml Datei welche im %appdata% Ordner liegt.

So verringere ich das Risiko, dass jemand an die Daten kommt, als es komplett für jedermann zu offen zu halten.

Ich hoffe, dass ist ein bisschen verständlicher, für das, was ich vor habe und warum ich das so mache, wie beschrieben ^^.

Was ist denn mit "einem dazwischen geschaltenen Service" gemeint ?

Ich habe mir da ein wenig was durchgelesen und erfahren, dass die Verbindungsdaten anscheinend auf einem Webserver gespeichert werden. Was mir bei meinem Programm aber nichts nützt, da wie erwähnt jeder Anwender eine andere Datenbank benutzt.

5.658 Beiträge seit 2006
vor 6 Jahren

Weeks of programming can save you hours of planning

X
xKushGene Themenstarter:in
91 Beiträge seit 2017
vor 6 Jahren

Das mit der Verschlüsselung bekomme ich ja soweit hin. Nur mein Problem wie im Titel ist immer noch, dass ich nicht weiß, wie ich connectionStrings in connection.config auslagern kann, da ich immer nh Fehlermeldung bekomme, obwohl ich es genauso mache, wie bei Microsoft beschrieben:

https://msdn.microsoft.com/de-de/library/ms254494(v=vs.110).aspx#Arbeiten mit Anwendungskonfigurationsdateien

Ich habe meine app.config nun mit aspnet_regiis.exe "verschlüsselt" aber wie Abt schon meinte, ist das nicht die sicherste Variante. bzw. kann man die app.config mit aspnet_regiis.exe auch direkt wieder entschlüsseln.

Wie ich schon sagte, behebt das nicht direkt das Problem, aber es macht es schwieriger für Personen die nicht mal wissen, dass es sowas wie aspnet_regiis.exe gibt wie ich vorher zum Beispiel. Somit habe ich eine Angriffszielgruppe weniger.

Klar wird die NSA oder der BND immer noch an die Daten kommen.

P
1.090 Beiträge seit 2011
vor 6 Jahren

Fehlermeldung:
Zusätzliche Informationen: Die configSource-Datei "connections.config" kann nicht geöffnet werden.

Schau mal ob die Datei wirklich in deinem Anwendungsverzeichnis liegt und geöffnet werden kann.

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern

16.841 Beiträge seit 2008
vor 6 Jahren

Dass hier fünf Threads vom gleichen Benutzer zum gleichen Thema existieren: wow. Wäre mir das früher aufgefallen, würde dieser Thread gar nicht mehr existieren.
Wenn man die Thread so durchliest: es ist eigentlich alles zu diesem Thema gesagt.

Klar wird die NSA oder der BND immer noch an die Daten kommen.

Jeder, der die Grundlagen von .NET kennt, kommt damit an Deine Zugangsdaten.

Wenn das tatsächlich Kundendaten sind, wovon ich aufgrund des Namens "firmenkundentabelle" ausgehen muss, sind das höchst riskante Daten.
Sowas kann im Rahmen von Datenschutzgesetzen eine Gesetzesverletzung sein, die sowohl die Firma wie auch Einzelpersonen haftbar gemacht werden kann.

Sicher, dass Du hier mit der Sicherheit "spielen" willst...?

5.658 Beiträge seit 2006
vor 6 Jahren

Klar wird die NSA oder der BND immer noch an die Daten kommen.

Dein Angriffsszenario ist doch, daß jeder, der den Connectionstring hat, in der Datenbank beliebige Daten ändern, hinzufügen oder löschen kann. Und den ConnectionString zu verschlüsseln ist auch kein besonders großes Hindernis dabei.

Dafür gibt es Lösungen, wie von Abt bereits erwähnt. Man macht nicht einfach die Datenbank auf dem Server von außen zugreifbar für alle Clients, sondern verwendet eine API. Dort ist dann genau definiert, wer wann welche Änderung an den Daten vornehmen kann oder welche Daten genau abgefragt werden dürfen. An die Datenbank direkt kommt man aber von außen nicht ran.

Damit ist nicht nur sichergestellt, daß ein Benutzer nur das machen kann, für das er eine Berechtigung besitzt, sondern auch, daß die Daten in der DB immer konsistent bleiben.

Ich bin wie schon mal woanders erwähnt derzeit in einer sehr schlechten Ausbildung und muss mir das meiste selber beibringen.

Niemand hindert dich daran, die unzähligen Tutorials, Videos und Code-Beispiele im Internet zu lesen und zu studieren. Damit würdst du im Endeffekt wesentlich schneller vorankommen, als mit deiner Trial&Error-Herangehensweise.

Dein primäres Ziel ist ja auch nicht, Daten vor irgendwelchen Geheimdiensten fernzuhalten, sondern am Ende deiner Ausbildung eine Anwendung schreiben zu können, die den grundlegendsten Anforderungen im IT-Bereich entspricht.

Stichworte für die Suche wären z.B. Client-Server-Anwendungen, REST-API, WCF usw.

Weeks of programming can save you hours of planning

X
xKushGene Themenstarter:in
91 Beiträge seit 2017
vor 6 Jahren

Fehlermeldung:
Zusätzliche Informationen: Die configSource-Datei "connections.config" kann nicht geöffnet werden.

Schau mal ob die Datei wirklich in deinem Anwendungsverzeichnis liegt und geöffnet werden kann.

Die connections.config ist im selben Ordner wie die App.config.

@MrSparkle
Danke für die Stichworte, ich werde mich ran setzen.

Wie schon erwähnt geht es in diesem Topic auch nicht um die Verschlüsselung selbst, sondern nur um den Fehler den ich nicht verstehe, das ich den connectionString von der App.config nicht in connections.config auslagern kann, obwohl ich das Tutorial von Microsoft 1 zu 1 verfolgt habe.
Allerdings bin ich anscheinend vom Thema abgeschweift weshalb wir uns auf einmal über die Sicherheit ausgetauscht haben.

Zwecks der Sicherheit werde ich mir die von MrSparkle genannten Stichworte gründlich anschauen. Aktuell verschlüssel ich nur das Passwort der Einloggdaten mit SHA251 und Salting. So wird in der user.config auch nicht das Passwort als Rohtext angezeigt, sondern als generierter Key, der ja dank dem salting immer anders ist.