19

I have an Asp.net MVC project authenticating through AD. I would like to store audit information in tables for the current logged in user. What should I be storing in the database? I am currently using SamAccountName for my membership and role providers. Should I be using this? Should I use the more verbose and modern UserPrincipalName? What if we eventually end up using multiple domains?

What about Guid? Guid would seem like the obvious choice but I know nothing about it. Why is it nullable? Does this value change? What is it used for?

Update

According to SID vs. GUID ...

The reason for using SIDs at all, and not GUIDs, is for backward compatibility. Windows NT uses SIDs to identify users and groups in ACLs on resources.

SIDs will actually change if you move a user to a new domain, the GUID will remain constant. It looks to me like GUID is the way to go unless you intend to authenticate against a NT4 AD server.

I'm not sure what to do here as I cannot accept my own answer for 2 days. Most in-depth explanation wins?

Jim Mitchener
  • 8,835
  • 7
  • 40
  • 56
  • FYI. Documentation for .NET 4.5 says "This property will always return null when the ContextType property is set to Machine" – d0001 Jun 24 '14 at 22:35

4 Answers4

7

According to SID vs. GUID ...

The reason for using SIDs at all, and not GUIDs, is for backward compatibility. Windows NT uses SIDs to identify users and groups in ACLs on resources.

That being said, I've decided to go with GUID. SIDs will actually change if you move a user to a new domain, the GUID will remain constant. So long as you don't plan on running your application against an NT4 AD server, GUID is the way to go.

Jim Mitchener
  • 8,835
  • 7
  • 40
  • 56
2

You might want to use the SID -- that's what the OS itself uses in most cases. SIDs are also unique across domains or workgroups.

The problem with user name alone is that it can be changed, whereas the SID is fixed.

RickNZ
  • 18,448
  • 3
  • 51
  • 66
  • 1
    Also, the class representing the SID is `System.Security.Principal.SecurityIdentifier`, not `System.Guid` as the question and some other comments suggest. – Aaronaught Dec 16 '09 at 00:14
  • @Aaron Principal has both Guid and SID. – Jim Mitchener Dec 16 '09 at 00:16
  • There is a separate field in the Principal object called "Guid"; however, there is no requirement to associate a GUID with a user, so that field can be null. – RickNZ Dec 16 '09 at 00:18
  • According to the object browser SID can also return null. – Jim Mitchener Dec 16 '09 at 00:21
  • I see that, although I'm pretty sure that in order to be able to login as an AD user, that they must have a SID. – RickNZ Dec 16 '09 at 00:28
  • 1
    According to http://technet.microsoft.com/en-us/library/cc961625.aspx SIDs will change when you switch domains. GUIDs will remain constant. It looks like Guids are the best solution here. – Jim Mitchener Dec 16 '09 at 01:01
  • If a user changes domains, won't they also be using a different AD server? They may also have completely different permissions, in which case shouldn't they be considered to be a different user? – RickNZ Dec 16 '09 at 01:23
  • If they have different permissions then their group memeberships will change and the permissions in the application will change. But wouldn't you still want to identify who they were even if they couldn't use the application anymore? They are not a different person, they just moved. Also, GUIDs are much easier to store than SIDs. – Jim Mitchener Dec 16 '09 at 01:52
  • I guess it depends on the details of your application--I'm sure that's why GUID and SID are separate; GUID is certainly a valid alternative. In my apps, I have been more concerned with security context. I usually store the SID as a string, via ToString(). – RickNZ Dec 16 '09 at 02:25
  • 3
    You can use the `objectGUID` property if you want. Neither the SID nor the GUID are the "best", they are just different. If the information you are storing is security-related, use SID. If it is identity-related, use GUID. If it is both, use the GUID but store the SID to make it easier to query Active Directory and communicate with other AD libraries and AD-enabled apps. – Aaronaught Dec 17 '09 at 16:19
-1

If you are using ASP.NET MVC (or Webforms for that matter) with Windows Authentication, why not just use the user name that you get from this property:

HttpContext.Current.User.Identity.Name

This returns Domain/Username of the user. I have worked on corporate web apps that used this for auditing purposes. I would be curious to know if you think this is not unique enough for your purposes.

Also I'm not sure why you would want to store a SID or GUID of the user, as it is very hard to read compared to domain/user when you are viewing audit logs.

dso
  • 9,463
  • 10
  • 53
  • 59
  • Usernames can be changed. I'm also currently using SamAccountName so there is no domain information in Identity.Name, it's just a username. My primary concern is scaling in the future. – Jim Mitchener Dec 16 '09 at 01:43
  • 1
    How common is it that the user name changes (not the display name mind you, we're talking about the account name)? I've seen this being used for auditing in an org with 100K+ user accounts without complaints. Are you sure you're not overthinking this problem? – dso Dec 16 '09 at 06:49
  • 1
    Also I have seen cases where a user account name does change: when an employee leaves the company and returns. In this case however even the SID would change since it is considered a new account, even though it is actually the same person. If you want to truly ensure that its the same person then you would need to use a globally recognized unique identifier such as SSN. – dso Dec 16 '09 at 06:52
  • While I do see your point, did this 100k+ organization have policies in place to ensure username conflicts didn't arise? Such as never allowing the same username? What if an employee leaves with a common name, say "sjohnson" and their account is deleted. A new employee then comes on and gets the username sjohnson. This would cause some confusion in the application as to who did what. While I understand this would be quite rare, especially in a smaller organization, it could still happen. I'd rather be proactive about it. – Jim Mitchener Dec 16 '09 at 07:53
  • You should talk to someone who administers your domain to determine the policy before doing unnecessary work. In the org I worked for, two users with the same name never had the same user name, whether they were employees simultaneously or different points in time. I'm not sure how they ensured this (maybe they disabled accounts but didn't delete them), but I do know that changing names arbitrarily or re-using names for different people would cause many apps to break (email for example), so this is something the domain admins need to be concerned about. – dso Dec 16 '09 at 23:11
  • On second thought maybe you should post a question to serverfault, ask them what the right auditing strategy would be from IT admin perspective, since they are the ones that typically consume audit logs, as part of compliance audits or automated monitoring for example. You would probably get more insightful responses for this particular problem. – dso Dec 16 '09 at 23:24
  • 2
    User names change every time someone gets married or divorced unless the organization implements a username format that does not include any part of the user's name,e.g. employeeid, etc. Username changes are a very real headache for orgs > 1000 people. I know of a 10K org that had a security admin dedicated to handling name changes. – JimSTAT Sep 09 '12 at 14:13
-2

samAccountName is the user name the user uses to log in with. You can get a little more 'complete' by prepending the domain too, but there's no reason not to use the obvious username field.

gbjbaanb
  • 51,617
  • 12
  • 104
  • 148
  • 1
    Can't usernames change? What if, for example, a woman gets married and her surname changes, which also results in a username change? – Sam Oct 17 '13 at 00:07
  • Change the samAccountname to be a different name... that new login is still unique, so it still uniquely identifies the user. – gbjbaanb Oct 17 '13 at 08:23