Creating Active Directory of usernames for LDAP access - c#

I am a newbie to LDAP and Active Directories.
I need to build a active directory of users who are eligible to access a particular conputer. When the user enters the username and password in a web interface(created in C#) it is sent to the active directory via LDAP query to the active directory. AD will return users email address if the login is successful.
Is it possible to setup a Active Directory to achieve the above scenario locally? I am using Windows 7 Ultimate. I have installed ADAM for LDAP access.
Regards,
John.

Since you're on .NET 3.5 and up, 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
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);
// validate username/password combo
if (ctx.ValidateCredentials(username, password))
{
// if valid - find user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, username);
if (user != null)
{
return user.EmailAddress;
}
}
The new S.DS.AM makes it really easy to play around with users and groups in AD!
For ADAM (or AD LDS as it's called today), you could use
PrincipalContext ctx = new PrincipalContext(ContextType.ApplicationDirectory);
to establish a context with your ADAM directory - not sure, but you probably have to supply some form of additional information to know what Application directory to use (I've never played with this on ADAM). And also: I'm not sure if you can validate credentials against an ADAM store .... you'll just have to see and try!

Related

How can I securely ensure the current user belongs to an Active Directory Group?

I am creating a C# Winform Application which will be used in a corporate domain (Windows Active Directory). The app is to behave as the following:
When a user opens the App, the App checks if the current user is part of an Active Directory group.
If it is, the app then allows the user to use the app.
From google searches, I found several ways how to check if a user is part of an Active Directory group.
For example in the link here => How to check if a user belongs to an AD group?
My concern is the security part of this. What if someone spoofs a username and domain. He won't need to know the password to allow access to the app.
Don't do a look up. The SID of every group the user is a member of (recursively) is part of the user's login token. So you can just use WindowsPrincipal.IsInRole(). If you only have the name of the group, you can give it that:
var currentUser = new WindowsPrincipal(WindowsIdentity.GetCurrent());
currentUser.IsInRole("SomeGroup")
That translates the name into the SID and checks the login token for that SID. That requires a network request. If you can give it the SID of the group instead, then you can save that network request:
var groupSid = new SecurityIdentifier("S-1-5-21-blah");
currentUser.IsInRole(groupSid)

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

Accessing user info from a one way trust

I have two domains, MINE and THEIRS. MINE is my local domain and has a one way trust with THEIRS (using LDAPS port 636), so that MINE trusts THEIRS but THEIRS does not trust MINE. I can add users from THEIRS to groups in MINE, and have users from THEIR log into machines and applications on the MINE network. The trust appears to be working properly.
I am writing a little .Net application (not ASP.Net) to test connectivity over the WAN. We have one app that isn't seeing users from THEIRS in groups in MINE. Other apps, like SharePoint, work fine.
I tried using ASP.Net 4 option with System.DirectoryServices.AccountManagement objects, like PrincipalContext, UserPrincipal, GroupPrincipal, etc. Quick code snippet
PrincipalContext domainContext = GetDomainContext(DomainName, ConnectionPort,
UseSpecifiedCredentials, Credentials);
GroupPrincipal theGroup = GroupPrincipal.FindByIdentity(domainContext,
IdentityType.SamAccountName, GroupName);
PrincipalCollection theUsers = theGroup.Members;
var users = from u in theUsers
select u.Name;
return users.ToArray();
It all works GREAT when I connect directly to MINE. The issue comes in with connecting to THEIRS. Either the 1 way trust of the LDAPS traffic is returning the error:
System.DirectoryServices.Protocols.LdapException: The LDAP server is unavailable.
So I switch to .Net 2 variations using DirectoryEntry, DirectorySearcher, etc. This actually works against THEIRS domain.
List<string> userNames = new List<string>();
string searchString = string.Format("(sAMAccountName={0})", GroupName);
SearchResult result = SearchAD(DomainName, ConnectionPort, searchString);
I can connect directly to the THEIRS domain, using some impersonation in the code.
When I query the groups in MINE, I get back the SID for the users from THEIRS, not a user account.
The following users are a member of testGroup:
CN=S-1-5-21-....,CN=ForeignSecurityPrincipals,DC=MINE,DC=local
CN=S-1-5-21-....,CN=ForeignSecurityPrincipals,DC=MINE,DC=local
I tried the impersonation on this as well, running it as a user from THEIRS but no luck.
How can I get user info from THEIRS when the user is in MINE? Do I have to take the above CN/SID and query THEIRS domain? What am I missing in the .Net 4 stuff?
I assume you have your ASP.NET machine running in MINE.
Your System.DirectoryServices.AccountManagement approach should just work if you make sure you use a domain user account from THEIR domain to run the application. In normal one-way trust configuration (unless you are doing selective authentication trust), the domain user account from THEIR should have permissions to read from both MINE and THEIR.
To make sure you use a domain user from THEIR domain, you can simply set the AppPool identity. Of course, you can use impersonation to do it too.

comparing active directory and db user currently logged in?

How can i check that the current user logged onto the machine is an active directory user and also part of the application?
I am building an extension to a legacy application which authenticates based on AD. The database has ad_user_name and i want to compare the ad_user_name with the username actually held in active directory.
IF the usernames are the same then my edit view is accessible. If the users are different then something went wrong and they cant see anything.
EDIT: there is a possibility that the server only runs .NET 2.0
If your using .net 3.5 use this code instead.
To authenticate a user:
PrincipalContext adContext = new PrincipalContext(ContextType.Domain);
using (adContext)
{
return adContext.ValidateCredentials(UserName, Password);
}
If you need to find the user to R/W attributes to the object do this:
PrincipalContext context = new PrincipalContext(ContextType.Domain);
UserPrincipal foundUser = UserPrincipal.FindByIdentity(context, "jdoe");
This is using the System.DirectoryServices.AccountManagement namespace so you'll need to add it to your using statements.
If you need to convert a UserPrincipal object to a DirectoryEntry object to work with legacy code you can do this:
DirectoryEntry userDE = (DirectoryEntry)foundUser.GetUnderlyingObject();

How to query AD to get name email from lan id

I have some code in asp.net ( kindly given by someone else ) to query AD to get user name and email etc.
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using ActiveDs;
DirectorySearcher search = new DirectorySearcher(new DirectoryEntry(), string.Format("(samaccountname={0})", id));
if (search == null)
return id;
if (search.FindOne() == null)
return id;
DirectoryEntry usr = search.FindOne().GetDirectoryEntry();
IADsUser oUsr = (IADsUser)usr.NativeObject;
return string.Format("{0} {1}", usr.Properties["givenname"].Value, usr.Properties["sn"].Value);
However this requires impersonation with an id that's required to be changed every 2 weeks and then updated in the web.config which is often forgotten
Is there any non impersonation code to achieve the same result ?
UPDATE - it's a config tool and it looks up name, email id etc.
I like the service a/c idea
Q - How is it possible to run ( impersonate ) just the AD code with a "service" a/c ? any samples/code ?
how do you impersona
For your particular purpose, a ServiceAccount shall be added to AD;
If you ASP.NET application is for a LAN in your organization, you could simply forget about providing Username and Password and only provide the root domain. This way, Active directory will search for Windows authenticated user instead of using impersonnation (this assumes that the user accessing your application has the rights to perform the tasks provided by your application).
What exactly does your application need to do?
If your application manages user accounts, groups and OU, then you need to use impersonnation only if the user doing these tasks through the application has no rights of managing the AD with her/his regular user account. This, should not happen. So, event for this, if the user has the proper rights, omitting your credentials will only allow AD to search for the current logged on user.
We usually request IT to give us a domain service account. You still need to impersonate, but with a service account, the password will not have to be changed every 2 weeks, and is granted specific rights for the particular function you need it for, so it would mean very low maintenance for you.
I don't think so, because you need to bind to the domain with valid credentials in order to read from active directory.
Think of the username/password as part of a connection string to a database. I'd request a complex username and password from your domain administrator and request that they give it limited login permissions and set the password to never expire. Then store and use those in your Web.config file.

Categories