I am new to LDAP and active directory authentication , I just studied few things about LDAp authentication and done with sample application
I just checking Does the user exist in ActiveDirectory or not
public static bool DoesUserExist()
{
using (var domainContext = new PrincipalContext(ContextType.Domain,Environment.UserDomainName))
{
using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, Environment.UserName))
{
return foundUser != null;
}
}
}
in our local system its working fine , But when i hosted in ActiveDirectory Server and i am trying to access this with server IP address, i am facing some issue like
ContextType.Domain,Environment.UserDomainName and Environment.UserName
for these three values are coming from server Information not the users who accessing this application
So please help me how to get the User information(who accessing this application) so that i need to pass those info to server and need check for user is activedirectory user or not
Environment.UserDomainName returns the domain part of Environment.UserName, e.g. "mydomain.com", so you don't want that.
Environment.UserName itself will return the user who is currently "logged in to Windows", i.e. the app pool user - see MSDN.
You are better off checking the identity of the current web request, so in a MVC Controller or WebForms Page, use this.User.
Or if you are using Windows Authentication or hooking Forms Authentication into AD, the current Thread Principal should be the current request user, so you can use Thread.CurrentPrincipal.Identity.
Related
I am on a network with Active Directory. I wrote an MVC c# web application to show the person's name using the website in the header. The code for that is
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
UserPrincipal user = UserPrincipal.Current;
Debug.Writeline(user.DisplayName); //but when i host it in a local server (IIS) this keeps outputing my name
Whenever I access the website using some one else's computer I still get my name in the header.
How can I fix this so whenever I am on someone else's computer I get their name in the header?
UserPrincipal user = UserPrincipal.Current; will show the user that the web application is running under. UserPrincipal is used when you are looking up an user account from ActiveDirectory (using PrincipalContext).
You should use HttpContext.Current.User.Identity.Name to look up the user that is accessing the site but do check to make sure HttpContext.Current is not null.
Documentation on HttpContext class
I have a client-server application (both Windows, client is WPF, non-UWP) and i want to do authentication via active directory. My idea is to take the credentials (or a token) from the windows machine that the client is on and send that information to the server (via webservice, IIS, asp.net). the server then checks with ad if the credentials are valid and does authorization...
So the key points would be:
extract credentials/token from client-windows
send it via vebservice to server (that part should be simple)
validation on server against active directory
How can I achieve that?
If you want to check for a windows user authentication in a desktop application you can simpy use the
Environment.UserName
Variable, it provides the username of the current logged in user.
if you want to check if it is an active directory user you can call a function like this:
public bool UserExists(string username)
{
// create your domain context
using (PrincipalContext domain = new PrincipalContext(ContextType.Domain))
{
// find the user
UserPrincipal foundUser = UserPrincipal.FindByIdentity(domain, IdentityType.Name, username);
return foundUser != null;
}
}
With your new request you can split the code above:
In the client you can get the AD username and domain using Environment variable, pass it to the server and check if the user exist using the UserExist() function
I would like to use the app pool credentials to avoid a double-hop issue from a web API method. However, I do not want all requests to be impersonated but just this one particular request. The code currently looks something like this:
[Route("api/mycontroller/mymethod")]
public string GetDataFromOtherInternalSystem(int id)
{
var client = new WebClient ( Credentials = CredentialCache.DefaultNetworkCredentials);
return client.DownloadString('http://internaldomain/api/method/id')
}
From what I understand of MSDN, the user context is the logged in user for that browser session (i.e. my account going through Active Directory and not the app pool's account).
The credentials returned by DefaultNetworkCredentials represents the
authentication credentials for the current security context in which
the application is running. For a client-side application, these are
usually the Windows credentials (user name, password, and domain) of
the user running the application. For ASP.NET applications, the
default network credentials are the user credentials of the logged-in
user, or the user being impersonated.
This then creates the double-hop issue which could be eliminated if the request comes cleanly from the web application as the service account (without me having to construct credentials on the fly).
Any ideas on how to impersonate the app pool without me specifying user credentials as follows:
var cred = new NetworkCredential("myusername", "mypassword")
Again I'm trying to avoid the other web service being properly set up for Kerberos or CORS.
This can be accomplished by passing a null pointer (IntPtr.Zero) to the static Impersonate method of the WindowsIdentity class. Here is how it is described in the MSDN document for the Impersonate method:
Calling the Impersonate(IntPtr) method with a userToken value of Zero is equivalent to calling the Win32 RevertToSelf function. If another user is currently being impersonated, control reverts to the original user.
Usage would look something like the following:
using (var impersonationContext = WindowsIdentity.Impersonate(IntPtr.Zero))
{
try
{
// this code is now using the application pool indentity
}
finally
{
if (impersonationContext != null)
{
impersonationContext.Undo();
}
}
}
I'm working on a C# Web Application to allow read and write access to Active Directory user accounts.
I have got this working great on our main company AD- I can read accounts, get attributes, save details back to AD, enable/disable accounts etc. I'm using impersonation to do this, so just before it saves to AD it changes to using a different account (which belongs to Domain Admins), then reverts to the main app pool account after saving.
I've just been given the requirement to add user accounts through the app, but I'm not happy about testing this on the main AD, and I've therefore setup a VM with a test AD. I've got the app setup on that VM, and it reads from AD fine. I've setup the same user account that I impersonate on the live AD, and have added it to the domain admins group. However, when I try to save details to an existing user I get an "Access is Denied" error.
I know the impersonation is working as just before saving I output the result, and I tried changing the password and it failed with a different error.
I've asked our Network Administrator if he's setup anything special on the impersonation user for the live AD, but he says he hasn't, and they appear to be identical.
Does anyone know of anything else I might need to do other than add the impersonation user to the domain admins group? I've tried logging into the VM as the user, and have made a change to a user account through AD itself, so the user does seem to have the required level of access.
The following is the code I'm using to impersonate the user:
Impersonation imp = new Impersonation();
string impResult = "";
imp.ImpersonateDomainUser(out impResult, ConfigurationManager.AppSettings["ADAdminUserLogin"], user.Domain, ConfigurationManager.AppSettings["ADAdminUserPwd"]);
...
imp.Revert();
impResult returns the following:
Before impersonation: NT AUTHORITY\SYSTEM
After impersonation: TESTDOMAIN\user.manager.service
The code I'm using to save to AD is:
var entry = new DirectoryEntry();
var account = userName.Replace(domain, "");
var search = new DirectorySearcher(entry) { Filter = "(SAMAccountName=" + account + ")" };
search.PropertiesToLoad.Add(propertyName);
var result = search.FindOne();
if (result != null)
{
DirectoryEntry entryToUpdate = result.GetDirectoryEntry();
if (propertyValue == null || propertyValue.ToString().Length == 0)
entryToUpdate.Properties[propertyName].Clear();
else
entryToUpdate.Properties[propertyName].Value = propertyValue;
entryToUpdate.CommitChanges();
entryToUpdate.Close();
entryToUpdate.Dispose();
}
Any advice would be much appreciated.
This issue was down to User Access Control settings on the Virtual Machine.
Once I disabled User Access Control through the control panel, I was then able to save users to Active Directory. Its possible that running the browser as administrator may have also worked, though I didn't try this.
Is there a way to use a credential coming from the user's saved password list and use that instead of the local Windows credentials?
I need to look up a user's email address based on their Active Directory username to allow them to register for email updates via an intranet site. This seems easy enough if the user is actually logged into a machine directly that's part of the domain - I can use their identity name to search the AD based on their username:
using( DirectoryEntry root = new DirectoryEntry("LDAP://admachine.domain.local") )
{
using( DirectorySearcher searcher = new DirectorySearcher(root) )
{
// strip the domain from the username and find the user in AD
var username = Regex.Replace(Page.User.Identity.Name, #".*\\", string.Empty);
searcher.ReferralChasing = ReferralChasingOption.All;
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = string.Format("(&(objectCategory=user)(objectClass=person)(sAMAccountName={0}))", username);
var foundUser = searcher.FindOne();
// error checking occurs here...
var email = foundUser.Properties["mail"][0].ToString();
// TODO: stuff with the email address
}
}
However, if working from a PC at home this doesn't work. Page.Identity.Name resolves to the name I'm logged onto my own PC (MyMachine\Dave), ignoring stored credentials I used to authenticate with my work domain (WorkDomain\dave.downs).
The DirectoryEntry picks up and uses the saved credential just fine, allowing me to actually bind to and search the AD, but I can't find a way of then using it as the var username, which will contain of my local machine username instead.
Is there a way to actually do what I'm trying to do, or am I just going about things the wrong way/hitting my head against a brick wall?
I assume you are using IIS. Disable Anonymous Access and enable windows authentication. That way anybody who is not in the domain will get a popup that allows them to specify their domain user and password. For users that are coming from a domain enabled server nothing changes. But that way you guarantee that the identity will always resolve to a valide domain user. So this should solve your "I am seeing a non-domain user" problem. Check Windows Authentication Provider for details.
If they are logged in via Windows Auth, you can use:
System.Security.Principal.WindowsIdentity.GetCurrent().User
which will give you the sid of the logged in user.
Disable anonymous access and integrated security in IIS, force them to log in via basic auth under https. This will give make sure the the current session is running under an authenticated domain user.