MVC Active Directory Membership - c#

I am trying to make use of the active directory membership rather than SQL but there is very limited documentation available online. I have managed to connect my application to the domain controller without any problems but when you use "Context.User.Identity.Name" it comes up with DOMAIN\User. I want to basically drill down and get information such as full name, e-mail address, etc.
I just need a useful link and the searching I have done doesn't appear to have got me anywhere!
Many thanks

This should give you a bit of a clue: http://msdn.microsoft.com/en-us/library/ms973834.aspx
and here is a list of LDAP properties that you might want to play around with in the search result: http://www.computerperformance.co.uk/Logon/LDAP_attributes_active_directory.htm

Have you tried with this doc?
http://msdn.microsoft.com/en-US/library/system.web.security.activedirectorymembershipprovider%28v=vs.90%29.aspx
Can help?

If you are making use of Active Directory then you are likely using Windows Authentication. If so, all you need to do is:
Reference System.DirectoryServices.AccountManagement
In code (perhaps a controller action or model constructor)
// establishes your domain as the context for your user lookup
var principalContext = new PrincipalContext(ContextType.Domain, "domainName");
// gets the current user's UserPrincipal object
var userPrincipal.FindByIdentity(principalContext, #User.Identity.Name)
// example
var email = userPrincipal.EmailAddress;
Note:
This works because Windows Authentication means User.Identity on the current HttpContext is a WindowsIdentity and thus its Name property can be used to search AD.
You aren't limited to looking up the current user. You can use FindByIdentity() to search any value passed, and this method exists on other principals (ex. GroupPrincipal). You can also designate you wish to search by another type such as SID instead of Name.
Enjoy!

Related

Specifying incorrect container does not affect user search

I am using user the PrincipalContext class to connect to an Active Directory server and then use the ValidateCredentials method like this:
new PrincipalContext(ContextType.Domain, <some url>, <some container>);
principalContext.ValidateCredentials(userName, password, ContextOptions.Negotiate);
The some container parameter is of type Container and according to the documentation "All queries are performed under this root". Also according to this answer specifying the Container "... limits all queries using that DomainContext to the specified container."
The problem though is that against my companie's AD server if I specify a container that does not exist or just put in gibberish the AD server still finds a user if I specify a user that exists with the correct password.
Does anybody know why the user is still found? Is there some documentation you can point me to that explains this?
The simple answer is that ValidateCredentials doesn't use the specified container, simply because it doesn't need to. It doesn't actually search for the user. It just attempts to authenticate to the server with the credentials specified.
You can see the source code for ValidateCredentials here, which ends up calling CredentialValidator.Validate (an internal class).
In the constructor of PrincipalContext, it creates the CredentialValidator object, but you'll notice that it does not pass the container to it, only the name (the domain name).
_credValidate = new CredentialValidator(contextType, name, _serverProperties);
The _serverProperties variable is also built from only the server name, not the container, which you can see from the ReadServerConfig method.

How to work with ldap in .net C#

I have an application where i can send emails. Now am asked to use ldap in to and from fields of the email.Am very new to this concept. I have been given a ldap link. No idea how to proceed with that. Any aricle or hits will be greatly helpful.
If you're on .NET 3.5 and up and using Microsoft's Active Directory as your LDAP store, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
Basically, you can define a domain context and easily find users and/or groups in AD:
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");
if(user != null)
{
// do something here, e.g. get the user's e-mail address(es)
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
Most of the functionality I've used is in System.DirectoryServices.
Have a look at this link for more info: http://lozanotek.com/blog/articles/149.aspx
The LDAP link is basically a reference to a directory server, such as Active Directory, which will give you email addresses if you have their user name, for example. I'd start off by reading the article above, then experimenting with a small test program

active directory authentication with status/error code result

Currently we (myself and my company) have an asp.net mvc4 page. We wish to utilize a logon page which authenticates via AD. One requirement being with an unsuccessful attempt we give back some information to the user.
The information we would like to have would be something like:
Invalid user/pw
Account is locked
Password expired
This is unfamiliar territory so I'm not sure what .NET libraries may be available. So far I've only come across the System.DirectoryServices but it doesn't seem I will get results beyond a bool.
Is this possible? Any references, suggestions, or examples would be greatly appreciated!
You can use PrincipalContext.ValidateCredentials to validate your credentials first. If false is returned, use the static UserPrincipal.FindByIdentity to find your user then, if found, look to see if the account is locked out using IsAccountLockedOut().
You might need to extend UserPrincipal yourself to see if the password is expired, I'm not seeing a direct property/method. You can extend it to access the userAccountControl attribute directly and check to see if bit 0x800000 is set, which is PasswordExpired. Here is more information on the userAccountControl values.
Suppose you have code like this
try
{
SearchResult result = searcher.FindOne();
}
catch(Exception e)
{
// now what?
}
Now in Exception you can deal with LDAP exception type, Here is the List of all LDAP error's.
http://msdn.microsoft.com/en-us/library/aa746530(v=vs.85).aspx
You can identify on the basis of ADSI Error Value which type of error you are getting.
But according to me you should give user a single common error like invalid credentials because LDAP error are much hard to deal with.
Cheers.!!

Finding user's groups SIDs inside Sharepoint

I need to find out all AD groups SIDs that current user belongs to inside my Sharepoint (2007) webpart.
I wanted to use System.DirectoryServices.AccountManagement namespace:
using (var context = new PrincipalContext( ContextType.Domain ))
{
using (var user = UserPrincipal.FindByIdentity( context, accountName ))
{
var groups = user.GetAuthorizationGroups();
...
}
}
, but I get the following error:
Event ID: 10016
Through the permission settings (application specific) is the SID (S-1-5-20) for user NT AUTHORITY \ NETWORK SERVICE of address localhost (Using LRPC) is not authorized to activate (Local) for the COM Server application with CLSID
{61738644-F196-11D0-9953-00C04FD919C1}
This might be fixed with this http://support.microsoft.com/kb/899965
but this approach requires changing registry values (the ownership of the application, so you can change apps values at dcomcnfg) and later User Permissions at dcomcnfg's COM security, which isn't an option for me.
Is there another way to access Current user's groups SIDs inside Sharepoint?
I really hoped I can find these values in SPContext.Current.Web.CurrentUser.Groups, but apparently not.
You need to go the SharePoint way here and not use System assemblies, but the SharePoint ones.
The SID of each user is in the SPUser.Sid Property. As you want to look for AD groups only you can check the .IsDomainGroup Property of SPUser.
Now all you need to do is check the current user: ´SPContext.Current.Web.CurrentUser(aSPUser` object).
To answer your question how to get all groups a user belongs to, you actually will need to use System.DirectoryServices. A solution for your problem is shown in the following stackoverflow posts:
In C#, how to access Active Directory to get the list of groups that a certain user belongs to?
Querying AD for finding all groups of a user - Missing one group
So in short: SPUser object as well as querying the Active Directory via DirectoryServices

How to get Windows user name using different methods?

In .NET, there appears to be several ways to get the current Windows user name. Three of which are:
string name = WindowsIdentity.GetCurrent().Name;
or
string name = Thread.CurrentPrincipal.Identity.Name;
or
string name = Environment.UserName;
What's the difference, and why choose one method over the other? Are there any other ways?
Environment.UserName calls GetUserName within advapi32.dll. This means that if you're impersonating another user, this property will reflect that.
Thread.CurrentPrincipal has a setter and can be changed programmatically. (This is not impersonation btw.)
WindowsIdentity is your current windows identity, if any. It will not necessarily reflect the user, think ASP.NET with FormsAuthentication. Then the WindowsIdentity will be the NT-service, but the FormsIdentity will be the logged in user. There's also a PassportIdentity, and you can build your own stuff to complicate things further.
You asked for alternative ways.
Of course, you can always use the native Windows API: GetUserName.
I believe the property was put in several places so that it would be easier for the programmer to find. There's only one logged in user, and only one respective name.
The three methods are described as follow:
HttpContext = HttpContext.Current.User, which returns an IPrincipal object that contains security information for the current Web request. This is the authenticated Web client.
WindowsIdentity = WindowsIdentity.GetCurrent(), which returns the identity of the security context of the currently executing Win32 thread.
Thread = Thread.CurrentPrincipal which returns the principal of the currently executing .NET thread which rides on top of the Win32 thread.
And they change in result depending on your IIS configuration as explained in this article:
http://msdn.microsoft.com/en-us/library/aa302377.aspx

Categories