I am using Windows Authentication in an ASP.net MVC application. I would like to query Active Directory to get a users e-mail address based on the current user:
IPrincipal principal = HttpContext.Current.User;
Is there a way I can use Active Directory to query for their e-mail address?
using (var context = new PrincipalContext(ContextType.Domain)) {
using (var user = UserPrincipal.FindByIdentity(context, userName)) {
if (user != null) {
return user.EmailAddress;
}
}
}
Related
I need to store additional user properties per user when using windows authentication and based off AD groups. What is the easiest way to do this?
Here is my code to check that a user belongs to an AD Group, i'd like this to run per user that logs on:
var domain = HttpContext.Current.User.Identity.Name.Split('\\')[0];
using (var ctx = new PrincipalContext(ContextType.Domain, domain))
using (var user = UserPrincipal.FindByIdentity(ctx, HttpContext.Current.User.Identity.Name))
{
if (user != null)
{
var groups = user.GetGroups()
.Select(x => x.SamAccountName);
if (groups.Contains("Special User"))
User.IsSpecial = true;
//something like this would be ideal
Then I would like to be able to check the property throughout the app:
public ActionResult Index()
{
if(User.IsSpecial)
{
...
}
}
Basically I need to check the AD groups of the user once to set the property and then use the property subsequently to alter page behaviour.
EDIT:
In line with #Matthijs suggestion below I had a look at Claims authentication but I can't get my claims to persist between requests. Any suggestions on how to do this? I add the claim in global.asax and read the value in my controllers.
protected void Application_AuthorizeRequest()
{
var claimsPrincipal = User as ClaimsPrincipal;
var claimsIdentity = User.Identity as ClaimsIdentity;
if (!claimsPrincipal.Claims.Where(x => x.Type == "Client").Any())
{
var domain = User.Identity.Name.Split('\\')[0];
using (var ctx = new PrincipalContext(ContextType.Domain, domain))
using (var user = UserPrincipal.FindByIdentity(ctx, HttpContext.Current.User.Identity.Name))
{
if (user != null)
{
var groups = user.GetGroups()
.Select(x => x.SamAccountName);
if (groups.Contains("Special User")
{
claimsIdentity.AddClaim(new Claim("IsSpecial", "Yes"));
}
Controller:
var claimsPrincipal = User as ClaimsPrincipal;
var isSpecial = claimsPrincipal.Claims.Where(x => x.Type == "IsSpecial").First().Value;
You could use Claims for that. The .NET Core documentation provides more details about the usage of claims. It is possible to create your own claims, like IsSpecial.
More information about claims can be found in this answer on StackOverflow.
I've a server with AD installed. In this server I created a user and added him to the "Domain Admins" group.
In C#, I used the win32 function LogonUser and authenticated with the user added to the "Domain Admins" group. The authentication successed but when I retrieve all the groups using WindowsIdentity and IdentityReference I don't get the "Domain Admins" Sid.
Any idea why is that?
This is the code I'm using:
if (LogonUser(username,
domainName,
password,
(int)LogonType.LOGON32_LOGON_INTERACTIVE,
(int)LogonProvider.LOGON32_PROVIDER_DEFAULT,
ref logonToken) != 0)
{
WindowsIdentity wi = new WindowsIdentity(logonToken);
foreach (IdentityReference oneGroup in wi.Groups)
{
GroupList.Add(oneGroup.Value);
}
return err;
}
Notice that oneGroup.Value holds the Sid of the group which the user is member of.
Why are you using an API call for this? You have System.DirectoryServices.AccountManagement to do this:
// Vaidate credentials
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
return context.ValidateCredentials(userName, password);
}
// To get user groups
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
using (UserPrincipal user = UserPrincipal.FindByIdentity(context, userName))
{
return user.GetAuthorizationGroups();
}
I'm trying to use the following code to get the local logged in user for my web application based on AD.
Here is what i'm trying;
string CurrentUser = WindowsIdentity.GetCurrent().Name;
PrincipalContext context = new PrincipalContext(ContextType.Domain, "isd");
UserPrincipal upUser = UserPrincipal.FindByIdentity(context, CurrentUser);
if(upUser != null)
{
}
However, it returns "IIS APPPOOL\DefaultAppPool" as the user and not isd\whoever
It's IIS7 and .net 4
Thanks
I have a method to retrieve a list of AD groups that a user belongs to. Here is the code:
public static List<GroupPrincipal> GetGroups(string userName)
{
List<GroupPrincipal> result = new List<GroupPrincipal>();
// establish domain context
PrincipalContext yourDomain = new PrincipalContext(ContextType.Domain);
UserPrincipal user = null;
// find your user
user = UserPrincipal.FindByIdentity(yourDomain, userName);
// if found - grab its groups
if (user != null)
{
PrincipalSearchResult<Principal> groups = user.GetGroups();
// iterate over all groups
foreach (Principal p in groups)
{
// make sure to add only group principals
if (p is GroupPrincipal)
{
result.Add((GroupPrincipal)p);
}
}
}
return result;
}
In both IE and Chrome, this can work fine, but in Firefox, it always gives me DirectoryServicesCOMException on the user = UserPrincipal.FindByIdentity(yourDomain, userName); I don't even have any idea what kind of exception that is. Can someone explain me what the error is and how to fix it? Thank you so much!
Change the call to look like this:
using (HostingEnvironment.Impersonate()){
user = UserPrincipal.FindByIdentity(yourDomain, userName);
}
You will need to make sure that your application pool has AD permissions. This will perform the underlying AD call using the credentials of the hosting environment (the web App Pool Identity) instead of the credentials of user, who may not have permissions to query the AD server.
I have a .NET MVC 4 application that uses Windows authentication. Some users are administrators, and need to be able to enter data on behalf of other users.
I have a text box where the admin enters the name of another user. How can I check to verify that the text entered is an existing Windows username?
You could use the FindByIdentity method:
string username = "Some username you retrieved from the TextBox";
using (var ctx = new PrincipalContext(ContextType.Domain, "YOUR_DOMAIN"))
using (var user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, username))
{
bool userExists = user != null;
// here you know whether the user exists or not
}
You can query the Active Directory of your organization for this.
DirectoryEntry entry = new DirectoryEntry("LDAP://DomainName");
DirectorySearcher Dsearch = new DirectorySearcher(entry);
String Name="Richmond";
dSearch.Filter = "(&(objectClass=user)(l=" + Name + "))";
See this article:
http://www.codeproject.com/Articles/6778/How-to-get-User-Data-from-the-Active-Directory