One of the more, ahh, interesting points about the two legacy systems I’m helping to maintain are that both of them use use essentially custom built security to authenticate and authorize (a&a) users. And neither are very good. The good news is that both of these applications are internal, so it isn’t the end of the world, yet…
Ok, now it is!
So the question that comes up is:
How do we improve the security of these systems?
Essentially (from my point of view) there are two things that can be done:
Improve the existing code by fixing the errors that have been made with the existing A&A systems. But that still leaves our team responsible for authenticating and authorising users. And a recent internal audit has shown up that the teams managing these kind of things are really poor at managing permissions (i.e. keeping them minimal), and removing users who should not be accessing the system anymore.
Use someone else’s authentication and claims system in out system. All of a sudden we just have to authorise a user based on the claim presented by someone else.
And if we can tap into a system that has some kind of management processes around it, even better…
Play the William Tell Overture! Here comes Active Directory!
So that’s that sorted out, we’ll just flip on Windows Authorization, give it all a quick test, jobs a good ‘un!
Sorry, what’s that, it doesn’t just work? And you’ve not got a asp.net application? Oooh…
So I’ve been investigating building an active directory authentication service. Most of the code I’ll show you here is based on the LdapAuthentication class in the Active Directory Authentication from ASP .NET article, though I have had to modify it. One issue that I had early on was working out what AD server to connect to which lead me to the MSDN article on Serverless Binding and RootDSE.
The first snippet (authenticate.cs) shows how it is possible to authenticate the user. Line 3 sets up the DirectoryEntry with a path to Active Directory and the username and password to authenticate. It is line 4, accessing the NativeObject that actually causes the authentication to happen.
Getting the claims for the user proved to be harder. .NET provides the DirectorySearcher, but actually being able to use it was problematic. Doing the search in the way suggested by the Active Directory Authentication from ASP .NET was failing for me as the internal AD is setup to not allow searching by authenticated users. It turned out that the trick here was to use the defaultNamingContext to set the search path (line 4). The rest of the claims.cs snippet is concerned with extracting the groups that the user belongs to.