In my application I have the following method which I pass the AD Username to it (example: Domain1\User1) and try to find the groups that user belongs to in Active Directory.
public ActionResult Login(string userName)
{
PrincipalContext up = new PrincipalContext(ContextType.Domain);
UserPrincipal users = UserPrincipal.FindByIdentity(up,IdentityType.SamAccountName, userName);
PrincipalSearchResult<Principal> groups = users.GetGroups();
IEnumerable<string> userGroupList = groups.Select(p =>p.SamAccountName);
return userGroupList ;
}
The code works perfectly, However I am guessing this code will failto work in an environment where there are multiple domains.
For example:
1) User try to login with (Domain1\User1) and it will go through,
2) User try to login with (Domain2\User2) the app will try to look for User2 in Domain1, and becasue there is no such user in Domain1 it will fail.
Is this true? if yes, how can I resolve this issue so it will works with multiple domain?
I needed to pass the Domain name as the second parameter when trying to instantiate new PrincipalContext object.
By doing this I was able to retrieve user groups with multiple domains.
So the code will be something like this :
PrincipalContext up = new PrincipalContext(ContextType.Domain,"DomainName");
Related
I'm working on a C# project which auto-creates new Active Directory users and let them access to the AD server.
I have made a general user with the following code, but since the user does not belong to Domain Admins, it could not access to the server.
Domain domain = Domain.GetCurrentDomain();
PrincipalContext context = new PrincipalContext(ContextType.Domain);
UserPrincipal principal = new UserPrincipal(context);
principal.Name = name;
principal.UserPrincipalName = name + "#" + domain.Name;
principal.SamAccountName = name;
principal.Enabled = true;
principal.SetPassword(password);
principal.PasswordNeverExpires = true;
principal.Save();
Is there a way to include which group the new user belong in the code? Or after creating the account, adding the user to Domain Admins group might be another solution but I couldn't figure out how to do this either.
Any advice would be appreciated.
You just need to find the group and add the user you created. Like this:
var group = GroupPrincipal.FindByIdentity(context, "Domain Admins");
group.Members.Add(principal);
group.Save();
The code will have to run with credentials that can add someone to the Domain Admins group, which is likely a domain admin account itself.
I'm having a bit of a problem when trying to add a new user or trying to access an already existing user in the Active Directory through my C# program.
var principalContext = new PrincipalContext(ContextType.Domain, "domain", "OU=Users,OU=SI");
UserPrincipal usr = UserPrincipal.FindByIdentity(principalContext, IdentityType.SamAccountName, samAccountStr);
It's throwing the "An operations error ocurred" exception. I found out that it's supposed to that if the user doesn't have the right permission for the Active Directory but I am running the program as administrator with the account of someone who can add users to the AD. So I really don't know what could be wrong. When I try to add a new user I try it like this:
var principalContext = new PrincipalContext(ContextType.Domain, "domain", "OU=Users,OU=SI");
UserPrincipal usr = new UserPrincipal(principalContext);
The code for the existing user already breaks when I call FindByIdentity. The code for the new user however breaks after I try to set some values for the new user principle. For example:
usr.Surname = sn;
The extended error says it's:
SvcErr: DSID-031007DF, problem 5012 (DIR_ERROR)
So any idea as to what might be causing it if it's not a permission problem?
You have to provide a full Distinguished Name for the OU, including the domain. This is not valid:
"OU=Users,OU=SI"
Something like this would be (if your domain was "domain.com"):
"OU=Users,OU=SI,DC=domain,DC=com"
I'd like to ask for your help with following issue. I am working on ad-hoc application, will be used only by me and just once.
Part of it is to perform password reset for over 3000 users in AD and send them new credentials.
I can read from AD as normal user, but I have to use privileged account to modify it. How can I do that? I know, I can use PowerShell and have it done in a seconds, but I'd like to learn how to do it in C#.
My code to search for user is simple
public class ADSecurity
{
public static string getUserName(string sam)
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, sam);
return user.Name;
}
}
How can I do the same, but as different user?
I've seen some guides, but none of them explained a-z ... just advice on how to impersonate, but nothing about how to use it. There was one article here about impersonation, but using LDAP protocol (DirectoryEntry). But as I understand, it is really slow.
Any advice appreciated. I need to run it 2 days from now, so in worst case scenario I use PowerShell to do it.
Thanks.
There are a few ways to do it:
Run your application under the needed credentials (Shift+right-click on the .exe file and use 'Run as a different user'). If you're just doing this once, this is the easiest.
Use the PrincipalContext constructor that accepts a username and password.
public class ADSecurity
{
public static string getUserName(string sam)
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, null, username, password);
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, sam);
return user.Name;
}
}
Use the DirectoryEntry constructor that accepts a username and password.
I'm not sure which example you're talking about that's "slow", but in my experience, using DirectoryEntry directly is almost always faster, as long as you use it correctly. The System.DirectoryServices.AccountManagement namespace (what you are using in your example) uses DirectoryEntry behind the scenes anyway.
Of course, options 2 & 3 require you know the password.
The company that I work for has two active directories (ad1.com, ad2.com) because it has two different stores that had nothing to do with each other and plenty of users but now the managers of both stores need a page in common.
So I need to create a login where the users could access using just their Active Directory username and password.
In the login page there should be a list to choose the active directory and after that the user Paul(paul#ad1.com) and the user Paul(paul#ad2.com) with their respective password should be able to access to the page.
I have the code needed for the logIn page for one AD and works great but I don't know if it's possible to make the page available for two ADs.
Do I need some extra configuration on the server?
I google this but didn't find anything related.
If you have the code required for one AD, you could very well use the same code with slight modifications to authenticate against another AD.
Based on the domain name, you can identify the settings for AD and perform your authentication.
In cases where you use two AD, only identifying the domain name matters E.g.
ad1\username or username#ad1.com. You will not be able to achieve a login without the user specifying the domain name.
Have you tried using LDAP Authentication and just definining it differently based on the dropdown list?
Something like:
string adPath = string.Empty;
string domainName = string.Empty;
switch (ddlOption.ToString())
{
case "ad1":
adPath = "ad1Path";
domainName = "ad1";
break;
case "ad2":
adPath = "ad2Path";
domainName = "ad2";
break;
}
LdapAuthentication adAuth = new LdapAuthentication(adPath);
if (adAuth.IsAuthenticated(domainName, username, password))
{
//redirect Logic
}
I am trying to change the User Account Property in Active Directory by using the UserPrincipal.
I have read that we have to use the special account which has the write access to the Active Directory rather than the current log on user. So, I created the special class to impersonate by using the Special Account. But I am still having the
System.UnauthorizedAccessException: General access denied error
at user.Save(ctx); line.
System.Security.Principal.WindowsImpersonationContext newUser = clsImpersonate.ImpersonateUser("ADUser", "ADPassword");
if (newUser != null)
{
PrincipalContext ctx = blAD.GetAdminPrincipalContext();
UserPrincipal user = blAD.GetUserPrincipal(this.SAMAccount);
user.Enabled = false;
user.Save(ctx);
newUser.Undo();
}
How can I achieve this requirement? Thanks.
What permissions have been delegated to your special user? It needs to be able to write userAccountControl on the users in question.
I wouldn't impersonate the account first off! Gain access through by passing the values through ad first.
For the real issue, look at the error:
Get the principalContect.
Get the userprincipal.
Do what you want to do.
Save it, why are u using undo? Delete the Undo().
To access the Principle as another user, define your PrincipalContext with the credentials of the user and use that PrincipalContext when getting the UserPrincipal.
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "domain.tld", "ADUser", "ADPassword");
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, this.SAMAccount);
if (user != null)
{
user.Enabled = false;
user.Save();
}
If you are still getting the UnauthorizedAccess Exception, it is likely because the account you are specifying does not have access to write the userAccountControl attribute on the user object in Active Directory/LDS.