Different configuration per URL in silverlight - silverlight

I need to change database and settings when my customers load the application (xap) on different URLs.
Examples:
client A connects on URL: www.clienteA.com/system
client B connects on URL: www.clienteB.com/system
The two urls above call the same xap file, but I need to change database and settings;
how I do that?

Do those URLs actually resolve to the same site/server? IMO, the easiest way to do this is to do it as part of your build process. When you publish the app for "client A", you use the web.config (etc) for that client - and ditto "client B". May SCM systems allow this type of per-client configuration, or it is pretty easy to do it with a few build scripts.
The alternative (if they absolutely must be the same physical code files on the same server) is to move this into the machine's web.config - much more complicated, but you can use the "location" node in web.config to specify connection-strings per IIS site, even if they resolve to the same files. I stress that this is risky, hard to verify, and easy to get wrong - the build process is my preferred option!

Related

connect to a database server without exposing a network share

this is quite simple to do in many databases, but I have not yet found a way to achieve this with Advantage in Server-mode over the network.
assume 2 PCs:
SERVER: running Advantage Database Server, and contains A database
CLIENT: contains a simple application, or even just Advantage Architect.
If the folder containing this database was shared via the OS (network share, with read/write permissions), then establishing connection is straight-forward.
I am however, precisely trying to avoid exposing a network share.
In Firebird, for example, this can be done using connection path:
SYSDBA#SERVER:C:\SomePrivateFolder\myapp.FDB
Isn't this the reason for exposing a port for the database (6262)?
What's interesting is that they offer something called "internet" connection. I highly doubt they would require a network share over the internet to access the database.
So, is this doable, and if so, would love a hint.
Thanks!
Edit:
following the answer below, adding more details.
SERVER contains 2 folders, each one with its ADV Dictionary:
C:\Data\mydata.add (not a shared folder)
C:\DataShared\mydata.add (shared folder)
I am able to connect to the second one using the connect path \\SERVER:6262\DataShared\mydata.add
to connect to the first one i've tried:
\\SERVER:6262\C:\Data\mydata.add
\\SERVER:6262\Data\mydata.add
\\SERVER:6262:C:\Data\mydata.add
none of which worked.
Note that I am not calling the stored procedure directly, but using the Delphi ADS components, which certainly internally call that same stored procedure.
I am certainly connecting as Remote (have the ADS Server launched on SERVER). For the other parameters, I am using TCP/IP as comm. type, and default ADSSYS / blank password.
with this setup in mind, what would the path be to connect to C:\Data\mydata.add on \\SERVER?
Thanks again
No need to expose your database on a shared folder. You'd only do that if using the LOCAL connection. If using INTERNET or REMOTE, then simply connect using API AdsConnect60(). Look it up on the help file.
UNSIGNED32 AdsConnect60( UNSIGNED8 *pucConnectPath,
UNSIGNED16 usServerTypes,
UNSIGNED8 *pucUserName,
UNSIGNED8 *pucPassword,
UNSIGNED32 ulOptions,
ADSHANDLE *phConnect );
Furthermore, you can hide the path where your data resides by using a server side Alias. Look it up on the help files. It is quite simple.
To simplify things, do this:
Run ads server configuration utility, go to "Configuration Utility" tab and inside that, go to "File Locations" tab. Write down path for Error and Assert Log Path. Let's assume it is c:. Let's also assume server is 192.168.1.1.
Now create a file named AdsServer.ini in that path (c:) with section: [ServerAliases] and a line adsdata=c:\data. Now use API function AdsConnect60 like this: AdsConnect60( "\\192.168.1.1\Adsdata\Mydata.add", ADS_REMOTE_SERVER, "adssys", "password", ADS_DEFAULT, &hConn ) ;
If you are working from Delphi or some other language make sure you check out the clases that are already built wrappers for the API.
It is all really-really well documented: http://devzone.advantagedatabase.com/dz/WebHelp/Advantage11.1/index.html?ace_adsconnect60.htm

C# SQL connection string best practice

I have a winforms application that connects to a database with a connection string and a generic user
"Database=DBADAS;Server=TMT123\\SQLEXPRESS;User ID=user; Password=*****;
After connecting into the database with a login dialog, we check if the user and password are existent in the user table from the database.
My question is now if this is a good practice? because basically in the connection string there is every information needed to crack the server.
There are a few ways to go about this safely. Since it's a Winforms app and not a web application, most of your security risks involve someone already in your network peeking at the connection string. This adds a layer of security in and of itself.
1. Hardcoded
You can hardcode the connection string that fetches the users into a DLL and make your application depend on that DLL. I only suggest this because it sounds like the "generic user" password is permanent; otherwise, you'd have to recompile code every time you changed the password, then deploy again. This is very secure, however, as the value isn't stored in plain text.
2. App.Config
You can stick it in a configuration file. Within a secured network, this is probably the most versatile option, as you can store multiple strings and easily update them without updating the full application. This goes well alongside settings like a "DebugMode" setting, etc. Using App.Config or another XML file is ideal, but you can roll a quick and dirty .txt file, too.
3. Database
Probably the most secure way of all, as you can encrypt your database and code your programs to fetch their connection strings and login information from that database by using an unrelated login. This allows greater control over what can be reached by the application when a user has not yet logged in. It also prevents the software from operating outside of the network, which may be desirable.
4. Internal API
Having a separate application serve this data divorces user capability from your concerns, as the API and your app can exchange verification keys to see if your app even has permission to try to connect. This is my personal favorite, but obviously the most work to set up.
5. Registry Entry
Depending on how you have this installed, it may work well to embed the tokens you need in the Registry. This guarantees the app requires admin permissions to install, and allows you to use Windows security to restrict access to the hive.
Again, since it's an internal non-web app, I wouldn't worry too much about the plain text of the connectionstring; if someone has gotten this far into your network, chances are you have much bigger problems already. I wouldn't leave it floating as a plain text file in a local directory, but any degree of security above that is probably acceptable for your purposes.
Encrypting Web.Config
Open Command Prompt with Administrator privileges
At the CommandPrompt, enter:
cd C:\Windows\Microsoft.NET\Framework\v4.0.30319
In case your web Config is located in "D:\Articles\EncryptWebConfig" directory path, then enter the following to encrypt the ConnectionString:
ASPNET_REGIIS -pef "connectionStrings" "D:\Articles\EncryptWebConfig"
Use Aspnet_regiis.exe tool with the –pef option and specify the application path as shown above.
Note: The parameter "connectionStrings" is case sensitive.
For Winforms: You need to rename your app.config to web.config encrypt it by using steps 1 to 3 and again rename it to app.config.
Reference: https://www.codeproject.com/Tips/795135/Encrypt-ConnectionString-in-Web-Config

How to determine at runtime if I am connected to production database?

OK, so I did the dumb thing and released production code (C#, VS2010) that targeted our development database (SQL Server 2008 R2). Luckily we are not using the production database yet so I didn't have the pain of trying to recover and synchronize everything...
But, I want to prevent this from happening again when it could be much more painful. My idea is to add a table I can query at startup and determine what database I am connected to by the value returned. Production would return "PROD" and dev and test would return other values, for example.
If it makes any difference, the application talks to a WCF service to access the database so I have endpoints in the config file, not actual connection strings.
Does this make sense? How have others addressed this problem?
Thanks,
Dave
The easiest way to solve this is to not have access to production accounts. Those are stored in the Machine.config file for our .net applications. In non-.net applications this is easily duplicated, by having a config file in a common location, or (dare I say) a registry entry which holds the account information.
Most of our servers are accessed through aliases too, so no one really needs to change the connection string from environment to environment. Just grab the user from the config and the server alias in the hosts file points you to the correct server. This also removes the headache from us having to update all our config files when we switch db instances (change hardware etc.)
So even with the click once deployment and the end points. You can publish the a new endpoint URI in a machine config on the end users desktop (I'm assuming this is an internal application), and then reference that in the code.
If you absolutely can't do this, as this might be a lot of work (last place I worked had 2000 call center people, so this push was a lot more difficult, but still possible). You can always have an automated build server setup which modifies the app.config file for you as a last step of building the application for you. You then ALWAYS publish the compiled code from the automated build server. Never have the change in the app.config for something like this be a manual step in the developer's process. This will always lead to problems at some point.
Now if none of this works, your final option (done this one too), which I hated, but it worked is to look up the value off of a mapped drive. Essentially, everyone in the company has a mapped drive to say R:. This is where you have your production configuration files etc. The prod account people map to one drive location with the production values, and the devs etc. map to another with the development values. I hate this option compared to the others, but it works, and it can save you in a pinch with others become tedious and difficult (due to say office politics, setting up a build server etc.).
I'm assuming your production server has a different name than your development server, so you could simply SELECT ##SERVERNAME AS ServerName.
Not sure if this answer helps you in a assumed .net environment, but within a *nix/PHP environment, this is how I handle the same situation.
OK, so I did the dumb thing and released production code
There are a times where some app behavior is environment dependent, as you eluded to. In order to provide this ability to check between development and production environments I added the following line to global /etc/profile/profile.d/custom.sh config (CentOS):
SERVICE_ENV=dev
And in code I have a wrapper method which will grab an environment variable based on name and localize it's value making it accessible to my application code. Below is a snippet demonstrating how to check the current environment and react accordingly (in PHP):
public function __call($method, $params)
{
// Reduce chatter on production envs
// Only display debug messages if override told us to
if (($method === 'debug') &&
(CoreLib_Api_Environment_Package::getValue(CoreLib_Api_Environment::VAR_LABEL_SERVICE) === CoreLib_Api_Environment::PROD) &&
(!in_array(CoreLib_Api_Log::DEBUG_ON_PROD_OVERRIDE, $params))) {
return;
}
}
Remember, you don't want to pepper your application logic with environment checks, save for a few extreme use cases as demonstrated with snippet. Rather you should be controlling access to your production databases using DNS. For example, within your development environment the following db hostname mydatabase-db would resolve to a local server instead of your actual production server. And when you push your code to the production environment, your DNS will correctly resolve the hostname, so your code should "just work" without any environment checks.
After hours of wading through textbooks and tutorials on MSBuild and app.config manipulation, I stumbled across something called SlowCheetah - XML Transforms http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5 that did what I needed it to do in less than hour after first stumbling across it. Definitely recommended! From the article:
This package enables you to transform your app.config or any other XML file based on the build configuration. It also adds additional tooling to help you create XML transforms.
This package is created by Sayed Ibrahim Hashimi, Chuck England and Bill Heibert, the same Hashimi who authored THE book on MSBuild. If you're looking for a simple ubiquitous way to transform your app.config, web.config or any other XML fie based on the build configuration, look no further -- this VS package will do the job.
Yeah I know I answered my own question but I already gave points to the answer that eventually pointed me to the real answer. Now I need to go back and edit the question based on my new understanding of the problem...
Dave
I' assuming yout production serveur has a different ip address. You can simply use
SELECT CONNECTIONPROPERTY('local_net_address') AS local_net_address

How to vary a config by host-header

I need multiple sites to all point to a common application, varying by host-header.
While the code / content for each each site is identicial each site does need a unique config, for things like connection strings.
What would be the best approach to set this up?
(The site is actually a Silverlight / WCF application, although I don't think that should matter.)
Either use msi installation package and allow set up all these values in installation wizard or use new web.config transformation syntax introduced in .NET 4.0 (you will have separate config and build target for each host header).
Edit - I didn't understand your question first:
You will have to install the application multiple times. You can't have single site with multiple different configs. But you don't have to copy libraries multiple times - you can use links (mklink.exe). It means you will have one central directory holding your shared content like bin directory and you will have separate directory for each site. Each of sites' directories will contain its own web.config and some content placed to root of your site + links to central directory. You will create create separate application for each site in IIS and map single host header to each application.
Other possiblity is handling this in your code and having everything in single web.config but IMO it is pretty bad and dangerous solution.

JSP website pre-database configuration

I'm working on a website in JSP (in GWT really, but on the server side, it's really just JSP), and I need to configure my database.
I know HOW to code in the database connection etc, but i'm wondering how/where the database config should be saved.
To clarify my doubt, let me give an example; in PHP, a website usualy has a config.php, where the user configures the database, user, etc (or an install.php generates it).
However, since JSP is bytecode, I can't code this info into my site and have the user modify it, nor can I modify it analogously to an install.php.
How should I handle this? what's the best/most common practice ? I've found NO examples of this. Mainly, where should the config file be stored?
There are several possibilities to do this, what I've seen done include:
Having database credentials in a special file, usually db.properties or some simple XML file that contain the required information (driver, url, username, password, any ORM parameters if needed). The properties file would be placed under WEB-INF or WEB-INF/classes; the downside of this approach is that the user would have to modify the file inside the WAR before deploying it to the application server.
Acquire the database connection via JNDI and expect it to be provided by the application server. This seems to be the most common way of doing this; on the upside, your WAR doesn't have to be changed, however, the downside is that configuring a JNDI data source is different for every application server and may be confusing if your system administrators are not experienced with Java technology.

Resources