When should server maintenance affect implementation descisions? - active-directory

Here's my situation...
I'm writing a .Net/C# security system (authorization and authentication) for a large collection of web applications that require a single sign-on process. I'm using Active Directory as a data store and have written a very nice prototype that communicates with AD through LDAP. This component retrieves information about the logged in user that I have stored in AD which I then use to set their security roles in .Net forms authentication.
1) All is good.
Not being a System Admin, or Network Engineer, I wasn't familiar with the amount of system administration involved with setting up an AD instance. I wasn't aware that for each domain, I needed a separate server and domain controller. As it turns out, there are like 9 different domains that my team requires to be set up for all of the different environments that we're going to be accessing AD...
env1.dev.mycompany.com
env1.qa.mycompany.com
env1.stage.mycompany.com
env2.dev.mycompany.com
etc
...So now I have placed on upon myself somewhat of an administrative headache because I'm going to have to maintain all of these machines (or VM's), which is something that I'm not necessarily sure I want to do.
2) All is not good.
The prototype is really solid, and AD makes for a very good database for the solution, but now I'm wondering if I should scrap the code and write a SQL Server data provider instead (I know .Net already provides one, but it doesn't alone fit my business requirements for authorization).
Anyway, so I'm trying to think through this problem from a high level perspective. In general, I keep tripping over the fact that I would be throwing a really good solution just because of some server maintenance? I'm wondering if anyone here has experienced a scenario like this and what exactly you decided to do.
Doesn't have to be specific to AD either, just a situation where you had to evaluate between a good software solution and it's server maintenance constraints.

In general, the usability of a product is what makes people to choose between it and similar products. If the product has bad usability, the users won't care how high quality its code is - all that matters to them is how easy and effective it is to use and how well it fills their needs.
Maintenance can be thought as one aspect of usability. I would make it top priority to have an easily maintainable product. In the long run that will save many hours of work from the administrators.
One way to think about it, is first designing what would be the most usable solution from the end user's/administrator's viewpoint, and then making it an intellectual challenge to actually implement that optimal solution. It will probably require more effort from the programmer, but the end result will be better.
For example ZFS is one product where maintenance has been taken care of well (although I have not used it personally). When it was designed, much effort was put into making it easy to administer the file system with ZFS's command line tools - and those design decisions affect all levels of ZFS (for example storage pools).
As another example, I've been recently planning how do maintenance in a future project of mine - a distributed database and application server. Thinking about how typical administration tasks will happen (installing/upgrading applications, adding/removing servers in the cluster, resolving hardware failure etc.), has helped me to sort out some design decisions. Some of them go quite deep into the architecture of the system (for example how applications and extensions are loaded at runtime, and how the servers find other servers in the cluster).

If setting up a single sign on system for a Windows system I be very likly to use AD. As a sys admin. I try to follow a single-source-of-data policy. AD is already holding much of my Windows user/security data. I would prefer to have all in there rather than a second system.
When setting up dev/test/prod environments I try to ensure that the closely match the Prod one, most especially in the area being worked on (where development efforts are being put, etc). So if setting up system to develop an interface with AD I would likely have multiple AD servers.
What options could simplify the admin?
Can you have 1 master server that you maintain in the standard manner and use something like a VMware copy process to maintain all or most of the others? Rather than doing something to 9 servers, keep the other 8 as copies of that mirror the master except for changes made to support dev/test?
Can you run multiple Dev or Test domains from 1 AD server?
Can you script action?
Can you reduce the number of environments, especially at the higher end of test? E.g. provide multiple dev environments and role up releases into a single Test one?

Why not simply use OUs instead of separate domains when testing? That is, have a single domain, but specify that users for particular versions must be found in a particular OU inside that domain. What you would do is in your search functions for looking up users, you'd specify the particular OU as the search root instead of the root of the domain. In each OU you could have ids that incorporate the environment to keep them unique, e.g., user_env1_dev, user_env2_dev, user_env1_qa, ...
I use AD a lot for my apps and never set up separate domains for development/testing.

Use a provider pattern and abstract your datasource calls.
Then you can configure it to use AD or SQL on the fly.
public abstract SSODataProvider {
public bool AuthenticateUser(string u, string p);
}
public ADSSODataProvider : SSODataProvider {
public override AutheticateUser(string u, string p) {
//do auth here
}
}
public SQLSSODataProvider : SSODataProvider {
public override AuthenticateUser(String u, string p) {
//call DB
}
}
public static SSODataProvider dataProvider;
if (ConfigurationSettings.AppSettings["SSODataProvider"] == "SQL")
dataProvider = new SQLSSODataProvider();
else
dataProvider = new ADSSODataProvider();
....
dataProvider.AuthenticateUser("sss","sss");

Related

Where should i access my Database

I'm curious how you would handle following Database access.
Let's suggest you have a Computer which Hosts your database as part of his server work and multiple client PC's which has some client-side-software on it that need to get information from this database
AFAIK there are 2 way's to do this
each client-side-software connects directly to the Database
each client-side-software connects to a server-side-software which connects to the Database as some sort of data access layer.
so what i like to know is:
What are the pro and contra's of each solution?
And are other solutions out there which maybe "better" to do this work
I would DEFINITELY go with suggestion number 2. No client application should talk to a datastore without a broker ie:
ClientApp -> WebApi -> DatabaseBroker.class -> MySQL
This is the sound way to do it as you separate concerns and define an organized throughput to the datastore.
Some benefits are:
decouple the client from the database
you can centralize all upgrades, additions and operability in one location (DatabaseBroker.class) for all clients
it's very scaleable
its safe in regards to business logic
Think of it like this with this laymans example:
Marines are not allowed to bring their own weapons to battle (client apps talking directly to DB). instead they checkout the weapon from the armory (API). The armory has control over all weapons, repairs and upgrades (data from database) and determines who gets what.
What you have described sounds like two different kind of multitier architectures.
The first point matches with a two-tier and the second one could be a three-tier.
AFAIK there are 2 way's to do this
You can divide your application in several physical tiers, therefore, you will find more cases suitable to this architecture (n-tier) than the described above.
What are the pro and contra's of each solution?
Usually the motivation for splitting your application in tiers is to achieve some kind of non-functional requirements (maintainability, availability, security, etc.), the problem is that when you add extra tiers you also add complexity,e.g.: your app components need to communicate with each other and this is more difficult when they are distributed among several machines.
And are other solutions out there which maybe "better" to do this work.
I'm not sure what you mean with "work" here, but notice that you don't need to add extra tiers to access a database. If you have a desktop application installed in a few machines a classical client/server (two-tier) model should be enough. However, a web-based application needs an extra tier for interacting with the browser. In this case the database access is not the motivation for adding this extra tier.

Database access control: Application or Database level control?

I have been developing an application in Access 2003 that uses SQL Server as the back end data store. Access is used only as a GUI and does not store any data. All the code in the application is written in VBA using ADO for data access.
In recent meetings the DBA that works in my organization has become increasingly concerned over the fact that the application logic controls what data is available for viewing and for update. The way I have been developing the application up until this point is to use a single database login for all access to the database. This database login is the only user allowed access to the database and all other databases users (other than DBA types) are restricted.
The DBA for this project is insisting that each user of the application have their account mapped to only those objects in the database to which they should have access. I can certainly see his concern and that is why I was hoping to ask two questions ...
Is having a single application level login to the database a bad practice? I had planned to implement a role based security model where the "access" users were given was dependent upon their application role. However, the application logic determined whether certain queries/updates were allowed to proceed.
Does anyone know of some resources (articles/books) that go over how to design an application where database access is controlled from within SQL Server and not through the application?
It is bad practice but as you have seen - that is how most applications "evolve" starting out as wide open to a few users and getting tightened down as more people (IT/DBAs) get involved.
Your DBA should be able to help out - almost all general SQL Server books have a chapter or two on users and roles and security. They will also be able to explain the nuances of the different security options and what works best in your environment.
Alot of the setup will depend on the environment and the application. For example - if all your users are on Windows (based) connections you will want to use Windows Authentication instead of SQL Authentication. If you have many various roles you will want to use SQL Server Roles. You may want to incorporate AD groups as well as roles (or instead of). Your DBA can help you make those decisions, or even make them for you, as you explain more about your application to them.
The people on SO can certainly provide our opinions as well if you post more information about the environment and application and usage.
In my opinion
Yes it is bad practice, as a user could use the credentials to access the database in another way, circumventing your applications access control and perform actions that they shouldn't be able to. If you are on a windows domain you can create a group in AD for each of the roles and assign users to the group, then apply permissions based on that group so you don't have to add new users to SQL.
If you go down the active directory route you can use an LDAP query to see what groups the user belongs to, and you can decide whether they should have access.
It'll be interesting to read the other responses on this.
You don't say what the size of your database is or the business environment, so the answer is - it depends, but the presumption would be that your DBA is correct.
In a corporate environment the primary concern is usually the data, not the application used to access it. Indeed the data will often have a longer life than the application and changing business considerations may dictate that the data is used, and potentially modified by, different sources and not just 'your' application. In this situation it makes sense to build in security at the database level because you are ensuring the integrity of the database no matter how it is accessed, now or in the future, legitimately or illegitimately.
For 'departmental' level applications, that is where access is limited to half a dozen or so users, the data is not business-critical, and there will never be a need to use the data outside the original application then application-level security tends to be more convenient and the risks are often acceptable. I have clients who sell bespoke vertical application software to small businesses using this approach and as there's no internal IT it's difficult to imagine how else one could conveniently do it without incurring high support overheads.
However one of the defining traits of a corporate as opposed to a departmental level situation is that in the former there will be a dedicated DBA and in the latter there probably won't even be dedicated IT support, so you almost certainly must view the database as a corporate asset, and hence you should follow your DBA's advice. It's more work defining the database objects and security, but the final result is you can be confident about the integrity of your database and you'll safe yourself work when the inevitable upgrade/extension comes around.

Where can I get a one-off server of Active Directory for Developing against?

We're not a windows shop, but one of our products is going to need to optionally integrate with Active Directory - things like SSO etc.
I'd really rather not go through the rigamarole of setting up a whole server just to develop against it and then leave it hanging around for testing purposes.
Is there a simple cloud-based service where I can purchase a server running active directory for a month or two just for development purposes? I looked into Amazon EC2 but it looks like you may still need to go through a significant set up (I may be wrong on this).
Even if you find a provider that can do hosted AD, I don't know if you'll be able to avoid the setup and configuration that goes along with it. Active Directory can be configured in so many different ways that adequately testing against it really demands more than just a default, vanilla AD domain. (I've had to deal with far too many applications that made unwarranted assumptions about how Active Directory is structured, and it's infuriating. Accounts aren't always in the default "Users" container! You can have multiple domains in a forest! Sometimes the CN isn't the userid! Aargh!)
Anyway... if you really do want to host AD on a cloud service, it can be done, but it's rare, and it sounds like it's fragile. Here's a link to a discussion on the Amazon Web Services developer forum about using AD on EC2:
http://developer.amazonwebservices.com/connect/message.jspa?messageID=150845
The document provided by garysu22 looks particularly useful, but it's also 25 pages of tweaks and workarounds... so again, lots of setup and configuration.
By the way, I'm concerned that Amazon's whitepaper on hosting AD on EC2, which used to be here...
http://developer.amazonwebservices.com/connect/entry.jspa?externalID=2435
...seems to have gone missing. I'm not sure what that means, but it would make me nervous.
(EDIT: I'm not the only one: http://justinbrodley.com/?p=60)
Now for an answer to a question you didn't ask...
I've developed against Active Directory very successfully using a local virtual machine running Windows Server and AD. I highly recommend it. You'll need a reasonably powerful machine with plenty of memory and storage, of course, but any modern development box should handle it without breaking a sweat.
With this sort of setup, you get all the niceties of a VM environment, like snapshot and rollback (so you can break stuff, even deliberately, and fix it quickly) and easy network isolation (you can make the VM visible to just the host dev box, for example)... and you can make the entire thing go away when you don't need it by just suspending the VM.
Of course, you'll still have to go through the initial AD setup and configuration, but for the kind of AD setup(s) you'll need, that's pretty easy. If you're going to be doing any serious development against AD, that's valuable experience you'll want to have anyway. Active Directory is its own sort of beast, with more than its fair share of idiosyncrasies; the better you understand it, the happier your customers will be.
Good luck!
I think you want AD Lightweight Directory Service. You can run it on any server without going through the whole AD setup/hardening process. You won't be able to use all of the AD tools against it (Users and Computers, and Trusts MMC plugins), but it will behave like AD for prototyping and development. If you see posts about ADAM (Active Directory Application Mode), AS LDS is just the latest name of the same idea.

Why aren't companies using LDAP as a central repository for other than users?

In every larger company I worked for they used LDAP as a way to access the central repository of user information, but very few have taken efforts to extend the schema to include objectClasses that aren't derived from inetOrgPerson.
Microsoft's Active Directory makes extensive schema extensions but very few commercial products leverage the capabilities of LDAP.
Is it because most LDAP developers don't know how to model beyond users? Find value in it but just haven't thought deeply about it? Have tried it and ran into performance problems? Something else?l
I've always thought LDAP was too high level for network administrators and too low level for software developers. Neither of them seem to be confortable with it.
There is the perception that since almost every enterprise application will use a relational database, then adding one more data source lowers the availability and reliability for the application.
The barrier to make custom schemas in LDAP is still high. In LDAP servers, you have to put the schema file in the schema directory, usually with root or administrative priviledges an restart the LDAP server; whereas current ORMs can create, update or verify relational database schemas when the application gets started.
Personally I think it's because LDAP is a directory, not a database. Directories are good for looking up people and their associated data, but they're not particularly good for tracking highly relational data -- which is what a lot of the rest of our data looks like. In fact, our use of LDAP is actually as a front-end to "people"-data, merging a lot of data streams into a single directory view. We still have the "people" data in the backend databases along with the rest of our institutional data and have only chosen LDAP (in our case ADAM) as a front-end to allow convenient lookup of the merged "people" data. Now that we're moving to web services as a means of accessing this data, I'm not sure that it even makes sense to continue down the LDAP route (except to support existing services that haven't been updated).
We have done work for some companies with 65Million LDAP records an none of the records were for people.
The data was a variety of items mostly for devices including:
* DHCP
* DNS
* Mac Addresses
* Location
* SN
* Brand
* Model
* etc....
-jim
I would think that it is due to A) the complexity of working with LDAP (much higher than SQL) and B) the fact that your product would be tied completely to it. That is, it would have no market outside of large organizations running LDAP. For less money and effort, I could build an app that works anywhere.
Now, internal applications written specifically for the organization that need access to other LDAP data are a different story. But you will obviously hear less about them because they are not commercially marketed.
I thought LDAP was highly optimized for fast, frequent reads. I don't think they'd scale for transactional systems.
The relational model and its expression in SQL is a powerful thing. I don't think it will be easily supplanted by LDAP or object databases.

Should application users be database users?

My previous job involved maintenance and programming for a very large database with massive amounts of data. Users viewed this data primarily through an intranet web interface. Instead of having a table of user accounts, each user account was a real first-class account in the RDBMS, which permitted them to connect with their own query tools, etc., as well as permitting us to control access through the RDBMS itself instead of using our own application logic.
Is this a good setup, assuming you're not on the public intranet and dealing with potentially millions of (potentially malicious) users or something? Or is it always better to define your own means of handling user accounts, your own permissions, your own application security logic, and only hand out RDBMS accounts to power users with special needs?
I don't agree that using the database for user access control is as dangerous others are making it out to be. I come from the Oracle Forms Development realm, where this type of user access control is the norm. Just like any design decision, it has it's advantages and disadvantages.
One of the advantages is that I could control select/insert/update/delete privileges for EACH table from a single setting in the database. On one system we had 4 different applications (managed by different teams and in different languages) hitting the same database tables. We were able to declare that only users with the Manager role were able to insert/update/delete data in a specific table. If we didn't manage it through the database, then each application team would have to correctly implement (duplicate) that logic throughout their application. If one application got it wrong, then the other apps would suffer. Plus you would have duplicate code to manage if you ever wanted to change the permissions on a single resource.
Another advantage is that we did not need to worry about storing user passwords in a database table (and all the restrictions that come with it).
I don't agree that "Database user accounts are inherently more dangerous than anything in an account defined by your application". The privileges required to change database-specific privileges are normally MUCH tougher than the privileges required to update/delete a single row in a "PERSONS" table.
And "scaling" was not a problem because we assigned privileges to Oracle roles and then assigned roles to users. With a single Oracle statement we could change the privilege for millions of users (not that we had that many users).
Application authorization is not a trivial problem. Many custom solutions have holes that hackers can easily exploit. The big names like Oracle have put a lot of thought and code into providing a robust application authorization system. I agree that using Oracle security doesn't work for every application. But I wouldn't be so quick to dismiss it in favor of a custom solution.
Edit: I should clarify that despite anything in the OP, what you're doing is logically defining an application even if no code exists. Otherwise it's just a public database with all the dangers that entails by itself.
Maybe I'll get flamed to death for this post, but I think this is an extraordinarily dangerous anti-pattern in security and design terms.
A user object should be defined by the system it's running in. If you're actually defining these in another application (the database) you have a loss of control.
It makes no sense from a design point of view because if you wanted to extend those accounts with any kind of data at all (email address, employee number, MyTheme...) you're not going to be able to extend the DB user and you're going to need to build that users table anyway.
Database user accounts are inherently more dangerous than anything in an account defined by your application because they could be promoted, deleted, accessed or otherwise manipulated by not only the database and any passing DBA, but anything else connected to the database. You've exposed a critical system element as public.
Scaling is out of the question. Imagine an abstraction where you're going to have tens or hundreds of thousands of users. That's just not going to manageable as DB accounts, but as records in a table it's just data. The age old argument of "well there's onyl ever going to be X users" doesn't hold any water with me because I've seen very limited internal apps become publicly exposed when the business feels it's could add value to the customer or the company just got bought by a giant partner who now needs access. You must plan for reasonable extensibility.
You're not going to be able to share conn pooling, you're not going to be any more secure than if you just created a handful of e.g. role accounts, and you're not necessarily going to be able to affect mass changes when you need to, or backup effectively.
All in there seems to be numerous serious problems to me, and I imagine other more experienced SOers could list more.
I think generally. In your traditional database application they shouldnt be. For all the reason already given. In a traditional database application there is a business layer that handles all the security and this is because there is such a strong line between people who interact with the application, and people who interact with the database.
In this situation is is generally better to manage these users and roles yourself. You can decide what information you need to store about them, and what you log and audit. And most importantly you define access based on pure business rules rather than database rules. Its got nothing to do with which tables they access and everything to do with whether they can insert business action here. However these are not technical issues. These are design issues. If that is what you are required to control then it makes sense to manage your users yourself.
You have described a system where you allow users to query the database directly. In this case why not use DB accounts. They will do the job far better than you will if you attempt to analyse the querys that users write and vet them against some rules that you have designed. That to me sounds like a nightmare system to write and maintain.
Don't lock things down because you can. Explain to those in charge what the security implications are but dont attempt to prevent people from doing things because you can. Especially not when they are used to accessing the data directly.
Our job as developers is to enable people to do what they need to do. And in the situation you have described. Specifically connect to the database and query it with their own tools. Then I think that anything other than database accounts is either going to be insecure, or unneccasarily restrictive.
"each user account was a real first-class account in the RDBMS, which permitted them to connect with their own query tools, etc.,"
not a good idea if the RDBMS contains:
any information covered by HIPAA or Sarbanes-Oxley or The Official Secrets Act (UK)
credit card information or other customer credit info (POs, lines of credit etc)
personal information (ssn, dob, etc)
competitive, proprietary, or IP information
because when users can use their own non-managed query tools the company has no way of knowing or auditing what information was queried or where the query results were delivered.
oh and what #annakata said.
I would avoid giving any user database access. Later, when this starts causing problems, taking away their access becomes very dificult.
At the very least, give them access to a read-only replica of the database so they can't kill your whole company with a bad query.
A lot of database query tools are very advanced these days, and it can feel a real shame to reimplement the world just to add restrictions. And as long as the database user permissions are properly locked down it might be okay. However in many cases you can't do this, you should be exposing a high-level API to the database to insert objects over many tables properly, without the user needing specific training that they should "just add an address into that table there, why isn't it working?".
If they only want to use the data to generate reports in Excel, etc, then maybe you could use a reporting front end like BIRT instead.
So basically: if the users are knowledgeable about databases, and resources to implement a proper front-end are low, keep on doing this. However is the resource does come up, it is probably time to get people's requirements in for creating a simpler, task-oriented front-end for them.
This is, in a way, similar to: is sql server/AD good for anything
I don't think it's a bad idea to throw your security model, at least a basic one, in the database itself. You can add restrictions in the application layer for cosmetics, but whichever account the user is accessing the database with, be it based on the application or the user, it's best if that account is restricted to only the operations the user is allowed.
I don't speak for all apps, but there are a large number I have seen where capturing the password is as simple as opening the code in notepad, using an included dll to decrypt the configuration file, or finding a backup file (e.g. web.config.bak in asp.net) that can be accessed from the browser.
*not a good idea if the RDBMS contains:
* any information covered by HIPAA or Sarbanes-Oxley or The Official Secrets Act (UK)
* credit card information or other customer credit info (POs, lines of credit etc)
* personal information (ssn, dob, etc)
* competitive, proprietary, or IP information*
Not true, one can perfectly manage which data a database user can see and which data it can modify. A database (at least Oracle) can also audit all activities, including selects. To have thousands of database users is also perfectly normal.
It is more difficult to build good secure applications because you have to program this security, a database offers this security and you can configure it in a declarative way, no code required.
I know, I am replying to a very old post, but recently came across same situation in my current project. I was also thinking on similar lines, whether "Application users be Database users?".
This is what I analysed:
Definitely it doesn't make sense to create that big number of application users on database(if your application is going to be used by many users).
Let's say you created X(huge number) of users on database. You are opening a clear gateway to your database.
Let's take a scenario for the solution:
There are two types of application users (Managers and Assistant). Both needs access to database for some transactions.
It's obvious you would create two roles, one for each type(Manager and Assistant) in database. But how about database user to connect from application. If you create one account per user then you would end up linearly creating the accounts on the database.
What I suggest:
Create one database account per Role. (Let's say Manager_Role_Account)
Let your application have business logic to map an application user with corresponding role.(User Tom with Manager role to Manager_Role_Account)
Use the database user(Manager_Role_Account) corresponding to identified role in #2 to connect to database and execute your query.
Hope this makes sense!
Updated: As I said, I came across similar situation in my project (with respect to Postgresql database at back end and a Java Web app at front end), I found something very useful called as Proxy Authentication.
This means that you can login to the database as one user but limit or extend your privileges based on the Proxy user.
I found very good links explaining the same.
For Postgresql below Choice of authentication approach for
financial app on PostgreSQL
For Oracle Proxy Authentication
Hope this helps!
It depends (like most things).
Having multiple database users negates connection pooling, since most libraries handle pooling based on connection strings and user accounts.
On the other hand, it's probably a more secure solution than anything you or I will do from scratch. It leaves security up to the OS and Database server, which I trust much more than myself. However, this is only the case if you go to the effort to configure the database permissions well. If you're using a bunch of OS/db users with the same permissions,it won't help much. You'll still get an audit trail, but that's about it.
All that said, I don't know that I'd feel comfortable letting normal users connect directly to the database with their own tools.
I think it's worth highlighting what other answers have touched upon:
A database can only define restrictions based on the data. Ie restrict select/insert/update/delete on particular tables or columns. I'm sure some databases can do somewhat cleverer things, but they'll never be able to implement business-rule based restrictions like an application can. What if a certain user is allowed to update a column only to certain values (say <1000) or only increase prices, or change either of two columns but not both?
I'd say unless you are absolutely sure you'll never need anything but table/column granularity, this is reason enough by itself.
This is not a good idea for any application where you store data for multiple users in the same table and you don't want one user to be able to read or modify another user's data. How would you restrict access in this case?

Resources