I have an MVC5 web app that I utilize the following to obtain current user info. I have enabled windows login for the web app on IIS.
private readonly string _userName = UserPrincipal.Current.DisplayName;
item.CreatedBy = _userName;
This works when running the app on my development machine, however when I publish to IIS, it throws exceptions:
The
(&(objectCategory=user)(objectClass=user)(|(userPrincipalName=)(distinguishedName=)(name=)))
search filter is invalid.
How do I get this to work on the IIS server to correctly obtain user info?
BTW - I've also tried this:
private readonly PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
var user = UserPrincipal.FindByIdentity(ctx, User.Identity.Name);
item.CreatedBy = user.DisplayName;
but to no avail.
This may be what you mean by "I have enabled windows login for the web app on IIS", but confirm that you have Windows Authentication enabled on IIS itself. Details on what's going wrong in your "to no avail" case may also be helpful.
Looks like anonymous authentication was still enabled on the Default Web Site in IIS. I disabled, and now it works with the following code:
private readonly PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
var user = UserPrincipal.FindByIdentity(ctx, User.Identity.Name);
item.CreatedBy = user.DisplayName;
Related
Writing a C#, Core 2.1, self-hosted web api to stand up an Identy Sewrver 4 instance...
Trying to use LDAP for (temp) user and role store. Yet, when I run the STS I am working on, I keep getting a "bad password" error when I query LDAP. I am working on my Laptop (in a workgroup), am running a DC in Hyper-V (domain).
I am trying to use System.DirectoryServices.AccountManagement and have a simple search setup as:
// Pass in userName as someone#domain.xyz
// Example: userName = keith#sol3.net
// Domain Controller is found at dc01.sol3.net
public static bool CanSignIn(string userName, string domainName)
{
using (var pc = new PrincipalContext(ContextType.Domain, domainName))
{
UserPrincipal user = null;
try
{
var name = userName.Split('#');
user = UserPrincipal.FindByIdentity(pc, IdentityType.Name, name[0]);
}
catch (Exception ex)
{
Log.Warning(ex, $"Could not find {userName} in Active Directory, Domain: {domainName}!");
}
return user != null;
}
}
I am wondering if:
I need to attach my laptop to the domain?
Using Kestrel is interfering?
Should I run in IIS Express mode?
Should I research how to run under HTTP.SYS?
What path will help here?
TIA
I think you need to manually authenticate using a password in order to query the directory. Using the method you detail in your question there is no way for the calling app to identify itself. If you want the app to run independently of the domain (i.e. not have to run as a domain user on a domain-joined server) then the best way would be to use a raw LdapConnection and bind a username/password NetworkCredential to it.
This example uses a pre-configured service account to query for a user by their primary email address:
var connection = new LdapConnection(ldapServerName);
connection.AuthType = AuthType.Basic;
//Additional connection setup omitted for brevity
connection.Bind(new NetworkCredential(serviceUserName, servicePassword));
var request = new SearchRequest(
baseDistinguishedName,
"(&(objectClass=person)(mail=" + EscapeFilterValue(emailAddress) + "))",
System.DirectoryServices.Protocols.SearchScope.Subtree,
null
);
SearchResponse response = (SearchResponse)_connection.SendRequest(request);
I am trying to display full name of user from active directory. It works fine on my local. But when I publish this code to IIS on server it shows display name as null. What may be the issue? My account is using windows authentication.
using (var context = new PrincipalContext(ContextType.Domain))
{
var principal = UserPrincipal.FindByIdentity(context, User.Identity.Name);
var displayName = principal?.DisplayName;
}
I had to use HostingEnvironment.Impersonate() in order to access my AD properties on my IIS server. (It worked without it on local)
using (HostingEnvironment.Impersonate())
{
// your code
}
Also, you'd have to change your Application Pool's identity from "AppPoolIdentity" to "NetworkService".
I have a SharePoint solution with a custom application where a user should be able to change some properties in his own Active Directory object.
I am doing the following:
PrincipalContext ctx = ActiveDirectory.GetPrincipalContext("lab");
UserPrincipal user = ActiveDirectory.GetUserPrincipal(ctx, "Administrator");
user.DisplayName = user.DisplayName + DateTime.Now.ToString("ddMMyyyyHHmmss");
user.Save();
I am logged in to SharePoint as the domain administrator and i am trying to change my own DisplayName.
What is wrong with my code?
Update 20.04.2016
I have built a small Console Application with the following code:
static void Main(string[] args)
{
try
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "lab");
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "administrator");
DirectoryEntry de = (user.GetUnderlyingObject() as DirectoryEntry);
user.DisplayName = user.DisplayName + DateTime.Now.ToString("ddMMyyyyHHmmss");
user.Save();
Console.WriteLine("OK");
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
This works fine! That means normally, that the Authentication goes wrong or the user which is logged into SharePoint is not getting used to connect to AD and do the changes. If this could be the case, how could i find out with which user i am doing the operation?
Update 20.04.2016 - 2
I have now tried to put the username and password in the PrincipalContext contructor as below:
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "lab", "administrator", "pass");
This works, too! That means now definitely, that the user which is logged in to SharePoint is not used to create the PrincipalContext. But why? Normally code is always executed in the context of the current user!?
How can i find out which user is used to create the PrincipalContext and how can i change it that the logged in user is getting used?
I had the same problem, I resolved it like this:
In IIS, in the advanced settings of my app -> In Identity I add my service account (example: domain\service-account)
In my active directory, I give to this service account full control on folder and sub-folder where I want to create/update user (you need to modify view to see security tab -> right click -> view -> advanced features)
If you already have that, check if your service account is not disabled
And now everything is working :)
I have MVC 4 web app deployed on 'Alpha' domain and web app is getting the Windows User details using the following code. We have trusted relationship between 3 different domains (Alpha, Beta and Gamma). When a user called Beta\bloggs login opens the web app following code returns the details of alpha\bloggs. Is there a way to get the right user from active directory.
Thanks in advance.
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
using (UserPrincipal user = UserPrincipal.FindByIdentity(context, username))
{
if (user != null)
{
HttpContext.Current.Session["FullUserName"] = fullName;
HttpContext.Current.Session["EmailAddress"] = user.EmailAddress;
}
}
}
As far as I understand, you should test against a global catalog.
Can you try to change you context like this :
PrincipalContext context = new PrincipalContext(ContextType.Domain, "DNSName.Of.GlobalCatalog.com:3268", "DC=yourcompany,DC=com");
Context.domain identifies the credential store to use. A connection to the correct domain would still be required to lookup information in another domain. Domain trust just specifies credential mapping, who in domain x maps to credential y in domain z.
I don't think that FindByIdentity can handle implicit domain trust lookups.
I have a web app on our intranet (VS 2005). There are a couple pages that don't require the user to be logged into the app (feedback and the default page). I am trying to get the domain and username to display and/or send with the feedback. Is there a way to do this without requiring the user to log in? I've tried this.Request.ServerVariables["LOGON_USER"] and this.User.Identity.Name, but neither of them worked.
Edit:
I should have mentioned most of the users have Windows 2000 on their machines. It works on my development machine (XP), but not on the production network (where I have 2000).
Theresa, I think this is what you're looking for...
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsPrincipal principal = (WindowsPrincipal)Thread.CurrentPrincipal;
WindowsIdentity identity = (WindowsIdentity)principal.Identity;
String userName= principal.Identity.Name;
Assuming you have turned Windows Authentication on in IIS for your site:
public string user_Name
{
get
{
string x = Page.User.Identity.Name;
x = x.Replace("YOURDOMAIN\\", "");
return x;
}
}
The x = x.Replace("DOMAIN\", ""); strips out the DOMAIN sectionof the user acccount e.g NISSAN\rmcdonough