i will develop utility program for a company with more than 1000 client and the program must be win application with .Net because my program will act with another program.
What is your suggest for place of app.config?
one scenario:
We put the app.config on the server that configured once and write a windows service for it that publishes the connectionString through TCP/IP Socket.
In Socket programming we don't need for anything because we just use a free Port for send ConnectioString from server to clients. My Scenario based on this approach. (Default port embedded in app).
Reading your question (I am deciphering a bit) I can see that clients may be separated from eachother, and even if it's just in the LAN, the following solution would work:
Develop a WebService whose only job is to give the ConnectionString when called.
This enables you to have an "easy" and robust way of doing this, and could implement it only on the local intranet for security.
Regardless of this, make sure you encrypt the Data and perhaps even RSA sign it good measure. This will give you a secure, robust and less time consuming solution to your problem.
The app.config belongs with the client app - I wouldn't even try and hack together something else. Ship it as part of your app and install it. Especially the connection strings cannot really be outsourced anywhere else.
We use a hybrid scenario where we have just about only the connection string in the app.config on every client, and anything else that needs to be configured is in a database table which everyone reads.
But the connection string can't really be centralized in the database..... how would you connect to the database to read the connection string then? :-) A classic "chicken-and-egg" problem.
So: just use app.config and put your connection string there (if needed, encrypt the <connectionStrings> section).
The only viable alternative would be to embed the connection string into the app itself - as a constant string in a "Constants.cs" file or something.
Marc
The ideal architecture would be to provide a service that acts as your data layer - your WinForms application would make calls on this service to perform all its interaction with the database. Not only does this provide an abstraction layer for your data access, but it centralises your data connectivity into a single area (your data service), so you can store your connection string securely on the server that hosts this data service.
If you want central configuration, I would put the configuration into Active Directory, under the CN=Services, CN=Configuration node.
I use an adaptive connection string that configures itself based on the network and/or machine that the application is running on. I wrote a blog post about this approach some time ago. The key is to override the SettingsLoaded event to reconfigure the baked in connection strings. This will work on any .NET Windows client application or DLL. I even used this technique within DLLs to control the connection string for web applications. It really makes deployment a snap!
Of course this is not the best approach for all scenarios. One drawback is that users and administrators can't change the connection string with the configuration file.
On your server you will have IIS, you can define a url http://myapp.myserver.com and you can put an xml page there, wherever your clients can be, when they start, they can query http://myapp.myserver.com/myapp-config.xml , and on this file you can store version, connection string etc.
And you will have to manually instantiate all variables that you intend to load from this xml instead of app.config, but its not difficult to store your connection string in your program in static variable initiated after reading myapp-config.xml
Shipping app.config at client's place is not good because in case if you need to change any values, change server or distribute load, it will be difficult to redistribute everything.
Instead you can also keep a check on version of xml, if version changes, you can notify to download new version from same server and upgrade their program.
Related
I've got some desktop experience, but am (brand) new to web programming. I've built a well-received C# WPF desktop app that stores data in a local (on user's desktop) SqlLite DB. I'd like to transition the app to remote data storage, probably with a MS SQL Server DB, hosted by a web-host service provider. One database there would hold all the various users data, access controlled by their own username/password.
In fact I've already done that as an experiment, and it functions. My concern is security: at the moment my in-code connection string just uses my db account/password. I'm not such a newb to know that's not a good idea. There must be a standard way to move that private information out of the code and into a sort of relay between the app code and the db. But I don't know the terminology, or what to ask for, despite a day of googling. So:
(1) User requests data save, say
(2) App sends SQL statement and user credentials to relay.
(3) Relay checks credentials against db records (using my db credentials, but that's ok, they're at least not stored in the apps's source code)
(4) Assuming ok, forward sql statement to db.
Is (something like) this a thing? What's it called? Or is there some other standard way to achieve the goal of keep my connection string completely out of the code? Where do I begin reading about how to implement it? How would I know if my web-host would support such a thing?
From the point of view of web-app operations, your connection string, from your dotnet app to your RDBMS server, is considered a secret. That means it's data you retrieve from a configuration file, and is never checked in to your git or other source control system. That connection string contains your RDBMS username and password, along with stuff like the name of your database and the server where it runs.
(If you did check in an RDBMS connection string to source control for any machine other than localhost, change that password. Do it now. Cybercreeps troll github looking for connection strings to steal and use for nefarious purposes. )
Dotnet web apps have a configuration file. It's an XML file called web.config. Connection strings go into that file in an XML stanza looking like this
<configuration>
<connectionStrings>
<add name="Name"
providerName="System.Data.ProviderName"
<!-- When deploying to production,
replace this connection string with one
to connect the production data base. -->
connectionString="Valid Connection String;" />
</connectionStrings>
</configuration>
Here's some info about retrieving that kind of connection string from your dotnet program..
I've had good luck putting a globally useless locally useful localhost connection string in that file, with some xml comments explaining that it needs to be edited when putting the web app on a public server. My example shows such comments.
It's also possible to edit a connection string with the web server's IIS Manager app. This setup -- either web.config or IIS Manager -- has good security.
The scheme you outlined is more complex than you need unless, heaven forbid, every one of your customers has a different connection string.
As I developped a WPF .NET Core Application that interacts with an online MySQL Database using EntityFramework, I noticed I had absolutely no way of protecting my Database from being read or modified using the easily accessible connection string if my app was deployed and someone code reversed it.
I searched a bit and found these few possible solutions:
Storing the connection string in an encrypted app.config using aspnet_regiis (but .NET Core seems to be more oriented on .json configuration files, and therefore cannot be encrypted using aspnet_regiis)
Obfuscating the source code using an c# obfuscator like ConfuserEx (if I understood correctly it's just making the connection string harder to read, but it remains possible to get it and mess with the DB right?)
Building and interacting with API instead that would do the changes to the DB (but even then how to make sure the API requests are truly coming from my WPF app and not from a malicious user?)
If you know any more precisions about these solutions or perhaps have another way of making it secure and safe to connect to an online Database, detailed steps/links are very welcome!
Building and interacting with API instead that would do the changes to the DB
This would be the recommended approach.
(but even then how to make sure the API requests are truly coming from my WPF app and not from a malicious user?)
You can't really.
When you embed some kind of access key or a public URL in a client application that you expose publicly, you basically accept the fact that it may be exposed. You should assume that a malicious user can extract the key/URL from the client app regardless of any obfuscation.
The service may reject requests from IP addresses that it considers to be misusing the API but it will still need to handle those requests.
Managing a public API is not trivial. You may want to consider hosting your app in a managed cloud.
After some researches and tests, I found that the proper way to prevent a malicious user from reading and messing up with the connected database (even if he gets access to the connection string) is by Limiting my app to only execute Stored Procedures that will give the minimum data required. And for stored procedures that will read or change a user's sensitive data, also by having in their required parameters the user's secret token, which would be a random string generated in SQL the same time the user registers.
The only issue remaining is if the hacker spams requests to try to bruteforce (even if it's almost impossible to bruteforce a very long and safe token), it might still makes the MySQL server overload or even crash. To prevent that from happening the only solution seems to use an API.
I have an application which is executed when a user logs out. This is achieved via GPO. The application needs access to a database.
My App.config contains the connection string. I tried to encrypt it using aspnet_regiis but I just read that this works only per machine. While it worked on mine flawless it of course crashed on other machines.
I can not find another way on how to protect the connection string in this scenario. I have no setup so I can not execute aspnet_regiis on the local machine. How do you usually handle this problem?
Could you deploy the key for encrypting the App.config via GPO? Where do I find that key?
It's very hard if not impossible to achieve this.
See: http://www.grouppolicy.biz/2013/11/why-passwords-in-group-policy-preference-are-very-bad/
You will need to create a service that recieves the requests and communicates with the database, this service will be run on your server and thus you can keep your connectionstring safe.
One way would be to create a webpage that recieves postdata from the clients.
I have created a forms application for my project. I want to host on my website for users to download and test it. Because I am using a configuration manager I have to include the config file along with the .exe as there is a back end remote database for the application. And of course I only now realize my connection string is there for all to see. I tried renaming the app.config to web.config, but the aspnet_regiis -pef command just returns a help menu when ran as admin on my vista machine! Even if this command works and I rename web.config back to app.config, will the machine which runs the app when downloaded automatically decrypt the connection string? So in conclusion what is the best way for a novice like to approach this dilemma? Why does aspnet_regiis -pef not run? I have also looked at other posts about this topic but unfortunately they have not worked for me so far.
Either create user/specific connection string, or wrap all your data access in some web services, where you can control the autorization.
Creating user specific connection string is the simplest, but may have impact on the DB charge. You can still keep one connection string, but using windows identity to connect. In both case, you will have to spent some effort to ensure users won't able to do more than what they are allowed to do.
Wrapping your data access in web services is far more manageable but will require an extra work to make it works. Maybe you can take a look at RIA Services. The advantages are multiples: you can control the permissions within the web services, and you are reducing the exposure of unwanted queries.
Please also note that even if you encrypt the connection string in the configuration file, any malicious user will be able to decrypt it. A simple decompiler will highlight your decryption key.
You could just store an encrypt the connection string in the app.config but you will have to include the encryption key somewhere in the application. Therefore this is not safe because everyone can just decompile the application or attach a debugger and extract the connection string. Or monitor the network traffic. Actually there is now way you can prevent this from happening - whatever your application can do can be done manually by everyone (with access to the application).
The flaw in the design is that the application needs direct access to the database in the first place. It is close to impossible to ensure that the database can not be corrupted in this scenario (unless the database is only used for reading data). Essentially you would have to replicate a large portion of your business logic at the database server to ensure that no sequence of requests will corrupt the state.
A better solution would be accessing the database only indirectly through a web service. This allows you to perform better and easier to implement server-side validation and even authentication and authorization per user.
I have a web service on iis that i'm calling in a simple console app
this web service is takes stuff out of a database
I changed the data base on a config file but it seems to still be calling the former data base
any tip?
If there are some cached database credentials within the application, simply recycling the application pool for which it is in will flush that out. If you're not familiar with the application pools, simply restart IIS and that will do the same thing.
If you don't have credentials cached, could you specify where the credentials are being stored, such as a web.config file, custom library, etc?
Make sure that the connection string is actually being used rather than it using the settings from the original dataset designer.
If you have used the dataset designer there will be a connection string setting in the settings file of the project. unless the connection string in your web.config is exactly the same then it will use the original.
You can check whether it is using the string you supplied by entering garbage in the web.config connection string and seeing if the webservice fails after you have restarted the website.
Hope that helps.
It's hard to offer this advice without sounding unhelpful, but in cases like these you just have to track through it, logging out the various important bits, like what connection string your components are using when they connect to the database, etc, and the answer will sooner or later come to light. I say this from experience.
There's not much that myself or other posters here can do but offer you the most general advice, like recycling the application pools. Your question is just too short and lacking in information, and the subject of web services is a very wide one.
So start by adding logging as I suggested and it might just work, or at least give us more to go on. All the best to you..
Are you setting the connection string in the client app.config or the web services web.config?