Syncing Active Directory with my Application
I've inherited an application with its own user database and login authentication 开发者_如何学JAVAscheme which cannot be replaced.
There is now a need to integrate with Active Directory.
I've implemented mixed mode (forms and AD) authentication, where I'm having issues is keeping the users in sync
I've added a column to our user database for the active directory account name. The admin will need to create a user in AD, Create it in our application, and then in our application, select the AD user that matches...
This feels dirty and naive, what better ways are there to do this.
One thing I recommend is not storing the account name in the database, but the guid for the AD user account. Then if some admin changes something the connection remains even though the username has changed.
You can use a CLR library within sql server and a sql job to periodically sync accounts between AD and the user database.
You could use a group, which the clr library can look for, pull in all the members, and then automatically sync - that is update/create/deactive accounts according to their ownership of the AD group. Then your admin will only need to create the user in AD, give them access to the group, and wait for the job to kick off. (or go kick it off manually)
I am currently involved in a project that is similar in some ways to what you described. I have found that creating a managed assembly called via SQL CLR functions was the best way to integrate with Active Directory. In the end, I do feel like the SQL CLR solution is elegant and manageable enough to support my needs into the future.
Since my project and the solution are not the exact same as your situation I don't have the perfect answer, however I do have some general advice if you go the route of using SQL CLR to integrate with Active Directory. Of course, you might still want to look into querying Active Directory as a linked server (as suggested by DarrellNorton in his answer)... this may suit your needs just fine.
If you do decide to go the route of SQL CLR you might find these notes helpful...
Using SQL CLR to integrate with Active Directory:
The nice thing about using SQL CLR to integrate with Active Directory is that you will be using managed code and you have most of the .NET Framework at your disposal in terms of what functionality you want to implement. The downside for me has been that you end up having to write a decent library assembly that is fairly resilient against exceptions to prevent any theoretical (or real!) impairment to your database engine's reliability.
Registering your assembly & using System.DirectoryServices
The first "gotcha" I ran into installing my assembly to SQL Server was that you have to register the System.DirectoryServices assembly in the database... by default it is not enabled. The following question and accepted answer cover the issue in detail. Hopefully this saves you some time knowing about the gotcha in advance.
Working with Active Directory in .NET
The other major thing I would point out is the resource I used to build my custom library. I found a great (although slightly old) How-To article on Code Project which was pretty much the primary source of reference for my entire implementation:
(Almost) Everything In Active Directory via C# on Code Project
You will find that this article covers everything from creating & managing users to working with domains and trusts.
The only issue I have with this resource is that it does not cover the child namespaces under System.DirectoryServices (e.g. AccountManagement, Protocols, ActiveDirectory). From what I have read, there are multiple ways to interact with LDAP in .NET. My hunch is that there may be a better / faster implementation that could be created with the right knowledge about all of these namespaces. This isn't to say my current implementation isn't fast enough for my needs... I just wonder if it could be better if I wrote "closer to the metal" via raw LDAP protocols (System.DirectoryServices.Protocols) or something.
I guess the best way to deal with this is using Forefront Identity Manager -> http://www.microsoft.com/forefront/identitymanager/en/us/default.aspx
its like BizTalk in Identity Management World, you can sync information to different heterogeneous infrastructure, including directories, databases, and line of business applications
You can query Active Directory as a linked server in SQL Server. You could write stored procs that would attempt to query either SQL Server tables or Active Directory and return the correct login information. There would be no copying or synchronizing of data.
Here's how to add AD as a linked server and query it (you have to use LDAP strings, though, hopefully you know the basics of AD): http://www.kodyaz.com/articles/active-directory-services-queries-using-openquery.aspx
One thing, as others have mentioned, is to not use the name as the key in your DB. Use the user's SID from AD as the key in your database, as this is persistent in AD and will not change. The GUID could be used too, but in some scenario's this may change i believe.
There are two approaches I would look into:
- Have your application 'lookup' the users in AD before adding them to the DB. So your applications "create user" screen would actually allow the admin to search AD for the appropriate users, then they would choose that user. You would then have all the information about the AD account, and could add that to your DB at the time of user creation. The association would always exist.
- Move all of the user creation process into your application. The admin would come to your system to create a user, and you could wrap creating them in AD, and adding them to the DB with the AD information in a single transaction. Note there is a good chance this would not be allowed in many organizations, as there are probably other things that happen in AD and need to be set. But it may work for you.
精彩评论