3

I'm trying to use Windows Identity Foundation for authorization in my WPF client/server (WCF) application that may or may not be run in the same trust environment as the active directory that provides authentication. For example, authentication may be provided by the active directory, but the application may run in the cloud and the user's profile roles/permissions for the application will be provided by the application database.

I feel I'm missing a fundamental piece of the WIF process in my head in order to fully understand what I'm supposed to do:

  1. User logs into the Windows domain using an Active Directory Username/Password
  2. The user opens my application.
  3. I reference the WindowsIdentity of the logged in user and can now look at their login token and all their configured roles/claims - but just like they can log into the domain, they could log into their own machine and would still have a WindowsIdentity token.
  4. I can tie the user's Windows Identity to their user profile in my database and grant them access to the specific functionality in my application that their profile allows them to.

The piece I am missing is that I have this WindowsIdentity instance from WindowsIdentity.GetCurrent()... how do I verify what generated this? i.e. Is it a local machine user or an active directory user and if it's an active directory user, how do I know that it's my bona fide active directory server?

For instance - a couple of scenarios:

Scenario 1

  1. The user names their local computer with the same name as my active directory domain
  2. The user creates a local user on that computer with the same username as a user they know exists on my active directory that has full administrative access to my application.
  3. They log into my application and for all intensive purposes they appear to have the same username as if the administrative user had logged onto my active directory.

In this scenario, the user has a local user account and not an active directory account and it has a spoofed identity created to purposefully circumnavigate application security.

I assume that there's some way to determine that this is a Windows Local User account and not an Active Directory user? I could make a call to my active directory for the user account with the username found in the WindowsIdentity and compare the SIDs to determine that this is in fact a spoofed user account and the user should be denied access.

Is this the correct way to do this? Is there some way I can tell from the WindowsIdentity that it was issued by my active directory and that this identity hasn't been tampered with?

Scenario 2

  1. The user creates a spoofed Active Directory server with the same name as my active directory and creates an account mimicking the same process as the local user described in scenario 1.

Now I have an active directory user with the same domain name and username the same solution I suggested for scenario 1 would solve the issue for this scenario as well, but it would again be nice to determine that this token wasn't created by my active directory just by examining the token.

Can someone clear up what I'm missing - or am I missing anything at all? Should I just be making a call to Active Directory to authenticate that the WindowsIdentity provided is allowed access to my application?

BobTheBuilder
  • 2,455
  • 2
  • 27
  • 39

1 Answers1

1

Simple answer: Your active directory is identified by more than just the name. When your computer joins the domain it exchanges a set of credentials. Spoofing an active directory or any other computer is much harder than merely creating a computer with the same name. Windows takes care of all the behind the scenes authentication between machines. Bugs and vulnerabilities aside you can be pretty sure that when you call WindowsIdentity.GetCurrent() there is an unbroken chain of thrust backed by different credentials to authenticate the user.

More complete answer: There are two types of windows authentication:

  1. The first type is among peers in a network (i.e. outside of a domain). In this case when a user in computer A is connecting to computer B it's actually using a local user of B. If the user in B happens to have the same name and password as the user in A then the authentication happens without user intervention. If not a login screen appears and the user needs to provide credentials for some user in B. In any case the user is actually loging in to computer B, and B doesn't need to trust or know about the local use in computer A.
  2. The second type is in a domain. I believe you can only add users from a domain if the computer itself is in part of the domain or in a domain with a trust relationship with it. In any case when the computer B will have a different set of credentials which allows it to authenticate the domain controller(s). Now when the user from computer A wants to login computer B asks the domain controller (which it knows and trusts) to authenticate the user. Once it gets the OK from the domain controller the user is accepted.

Windows supports various protocols for authentication some newer and more robust than others. The network administrator configures which protocols are accepted. Most (all?) protocols do not involve sending the actual password over the network (look at digest authentication for an example of such a protocol or read about the old NTLM protocols)

Eli Algranti
  • 8,707
  • 2
  • 42
  • 50
  • The problem is - let's assume my application isn't inside the active directory domain - how does my application know that the user is indeed a user of that active directory domain and not just some spoofed user? – BobTheBuilder Apr 15 '13 at 13:46
  • I've expanded my answer hope it answers your question. For the specific case I'm almost sure if your app is not part of the domain then the user needs to authenticate with a local user. If adding domain users while not in a domain is possible then your computer will have the domains controller credentials, and the domain controller is the one that authenticates the user. – Eli Algranti Apr 15 '13 at 23:13
  • *"Bugs and vulnerabilities aside you can be pretty sure that when you call WindowsIdentity.GetCurrent() there is an unbroken chain of thrust backed by different credentials to authenticate the user."* Is that also true of other `WindowsIdentity` instances (such as the one you can get from `Thread.CurrentPrincipal.Identity` if it's been set to a `WindowsIdentity` instance) if their `IsAuthenticated` is `true`? (This is the thrust of [my question here](http://stackoverflow.com/questions/33563758), which currently just has an answer that is...unconvincing but concerning.) – T.J. Crowder Nov 06 '15 at 13:25