I have an ASP.net app which is being hosted on a server. I want to get the Clients username from the system and use that name as a title for an XML file im saving on the server.
I have tried various different mathods such as:
Environment.UserName();
WindowsIdentity.GetCurrent();
However all that keeps returning is the NetworkService account name on the server.
Can anyone assist with this.
thank you
Given that your application has authentication set up (either Forms or Windows Authentication), you can get the current user's name via:
HttpContext.Current.User.Identity.Name
Your web application is running (by default) under the NetworkService account. If you want to know the username of the user's NT account you should check out impersonation. With that the application will be running with the credentials of the user.
For public websites this is not possible or shouldn't be done. But internal company applications could do so.
Try this:
HttpContext.Current.User.Identity.Name
This will only work if a user is authenticated by either Forms/Membership authentication or Windows, you can check beforehand:
string userName = "Anonymous";
if (User.Identity.IsAuthenticated)
userName = HttpContext.Current.User.Identity.Name
If your users are authenticated you can use User.Identity.Name
you want the user name of the web client and WindowsIdentity or Env.UserName return you the server side user name, which might be the same as the web client user name only if you have enabled authentication.
I think to solve your issue you should look in the Request headers, in one of those headers there should be a username or useragent string telling you what you need.
Related
I have a MVC 5 application which uses OWIN and identity2.0 for authentication.
My application require mixed authentication:
for users not a domain lets say "dom1", they should see a form based page
for users on domain "dom1" they should be logged in via windows authentication.
I want to know how can I get the domain name of user without authentication, at the time when user first hit my Account/Login action.
I have used :
PrincipalContext pcontext = new PrincipalContext(ContextType.Domain);
var domainName = pcontext.ConnectedServer;
and
System.Security.Principal.WindowsIdentity context = System.Security.Principal.WindowsIdentity.GetCurrent();
var domainName = pcontext.Name;
BUT both of these shows domain name of machine where website is deployed and not of the client's domain.
Any help is much appreciated and please correct me if I am doing any blunder.
"without authentication"? You can't. The Windows authentication has to be completed before you can see the user's account.
This is because of how Windows authentication works:
The browser accesses the site anonymously.
IIS returns a 401 response
The browser responds by making the request again with the Windows credentials included
IIS verifies the credentials with the domain controllers
IIS passes the verified Windows credentials to your application.
The only time your application can see anything about the user's account is at step 5 - after the authentication is successfully complete.
The domain can be seen here
Environment.UserDomainName
Gets the network domain name associated with the current user.
Per the MSDN documentation:
The UserDomainName property first attempts to get the domain name component of the Windows account name for the current user. If that attempt fails, this property attempts to get the domain name associated with the user name provided by the UserName property. If that attempt fails because the host computer is not joined to a domain, then the host computer name is returned.
If you're not authenticated, you'll unfortunately see the host computer name. No way around this that I'm aware of.
You can also get the ip of the client's request here
HttpRequest.UserHostAddress
I have a web site from where I fire a mail to members in my offices
This mail have a yes no button.
on click of yes/no button I call a web service, my yes no link looks somewhat like this
yes
Now users i.e. my office staff will login their system open their outlook find this mail and then click it.
After they click, takevotingOpt method in my web service will be called. In this method I want to know, from which user this call has came.
so that I can maintain record in database like xyz user has voted yes/no
say for e.g. their are two members in my organisation A and B
A's windows loginId is "AaLoginId" and
B's windows loginId is "BbLoginId"
both A and B receives the mail with the above mentioned link in it. when A click the yes/no link my web method should give me A's login Id i.e "AaLoginId". After I get this I make an entry in my database as A has voted yes.
I have tried below thing in my web service to get the user name but of no use please help.
tried this things to get windows login username.
//string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
//Uri uri = new Uri("http://tempuri.org/");
//ICredentials credentials = CredentialCache.DefaultCredentials;
//NetworkCredential credential = credentials.GetCredential(uri, "Ntlm");
////userName = credential.UserName;
//userName = User.Identity.Name;
//userName= System.Threading.Thread.CurrentPrincipal.Identity.Name;
//userName = Context.Request.ServerVariables["LOGON_USER"].ToString();
//userName = HttpContext.Current.User.Identity.Name.ToString();
I went to authentication in my inetmgr and enabled windows authentication for my hosted web service now it does what I want (userName = User.Identity.Name;) but it opens a browser window and ask for windows userid and password I dont want that It should pick up without login window.
Please help or suggest any other approach to achieve this.
You need to turn on windows authentication for the webservice and in IIS, then you should be able to look at Request object to get the user
Use Environment.UserName
Here's the MSDN docs.
http://msdn.microsoft.com/en-us/library/system.environment.username.aspx
Edit - To retrieve all users logged into the current system, check out this Question/Answer - Logoff interactive users in Windows from a service
It shows a way to use WMI and through system DLLs to retrieve a list of logged in users on the current system (which may or may not include service accounts, I haven't tried it myself).
Edit - Using Integrated Security would work for what you're trying to achieve, but can be a bit tricky to setup in large corporations. To get rid of the login prompt, Internet Explorer auto-authenticates to sites in the "Intranet Zone", but does not auto-authenticate to sites in the "Internet Zone". Make sure your web service URL is Intranet based, i.e. http://myserver/ and not Internet based i.e http://myserver.mycorp.com/, unless the user's are within the same domain. If they are not, have the users add "*.mycorp.com" to the Intranet Zone. FireFox has a similar configuration, where specific sites must be "trusted" in order to auto-authenticate.
IS it possible to get the windows LogOn username of client from web application.
and how does this actually works
Request.ServerVariables("LOGON_USER") also not works in this case as I don't want user to authenicate first
While
Dim ident As WindowsIdentity = WindowsIdentity.GetCurrent()
this is windows specific which gives the user where the code is?
How should I go with this.
found what I want
Context.Request.LogonUserIdentity.Name gives the logon user name..
How can I implement following in ASP.NET MVC application:
user opens intranet website
user is silently authenticated if possible
if NTLM authentication didn't worked out, show login form to user
user indicate login password and select domain from list of predefined domains
user is authenticated in code using AD
I know how to implement 4 and 5 but cannot find info on how to combine NTLM and forms.
So that NTLM native login/password dialog is never shown - transparent authentication or nice looking login page.
How should work?
Should user be asked login and password?
Can her current credentials (domain username) be used without asking to enter login and password?
UPDATE for these, investigating same problem:
When I was asking this I was not fully understand how NTLM authentication works internally.
Important thing here to understand is that if user's browser doesn't support NTLM properly or if NTLM support is disabled by user - server will never get chance to work around this.
How Windows authentication is working:
Client send a regular HTTP request to server
Server responds with HTTP status 401 and indication that NTLM authentication must be used to access resources
Client send NTLM Type1 message
Server responds with NTLM Type2 message with challenge
Client send Type3 message with response to challenge
Server responds with actual content requested
As you see, browser not supporting NTLM will not go to step (3), instead user will be shown IIS generated Error 401 page.
If user doesn’t have credentials, after cancelling NTLM authentication popup dialog window browser will not continue to (3) as well.
So we have no chance to automatically redirect users to custom login page.
The only option here is to have a “gateway” page where we decide if user should support NTLM and if so, redirect to NTLM protected home page.
And if not, show login form and allow authentication by manually entering login and password.
Decision is usually made based on users’ IP address and/or host name either by matching IP ranges or by checking table of predefined IPs.
This article might get you pointed in the right direction. Basically you have two apps in two virtual directories under the same host name. One app uses Forms authentication, one uses Windows. The one using Windows authentication creates a valid form authentication cookie and redirects to the second virtual directory.
ASP.NET Mixed Mode Authentication
I have this exact setup in production, I setup my portal to use FormsAuth and wrote a function that takes the visitors IP to look up the user account that is logged in to that IP / PC. Using the name I find (eg. DOMAIN\user), I verify the domain matches my domain and that the user name / account is valid in my FormsAth provider using Membership.GetUser(<user>). If this call returns a match and the user IsApproved I create a FormsAuthenticationTicket & cookie for the user. I have 400+ people on the network and this works perfectly, the only computers that still login are (1. Users without accounts in my portal, 2. A few MAC/Linux users, 3. Mobile users who did not boot on the network and had Group Policy enable their Firewall to High).
The catch to this solution is that it requires impersonation of a domain admin account to query the users PC, and that you use unmanaged code netapi32.dll.
Here is the code I use (external function calls not provided, for brevity). I've tried to simplify this a bit, since have LOTS of external calls.
string account = String.Empty;
string domain = String.Empty;
string user = String.Empty;
ImpersonateUser iu = new ImpersonateUser(); //Helper that Enabled Impersonation
if (iu.impersonateValidUser(StringHelper.GetAppSetting("DomainAccount"), StringHelper.GetAppSetting("DomainName"), StringHelper.GetEncryptedAppSetting("DomainAccountPassword")))
{
NetWorkstationUserEnum nws = new NetWorkstationUserEnum(); //Wrapper for netapi32.dll (Tested on Vista, XP, Win2K, Win2K3, Win2K8)
string host = nws.DNSLookup(Request.UserHostAddress); // netapi32.dll requires a host name, not an IP address
string[] users = nws.ScanHost(host); // Gets the users/accounts logged in
if (nws.ScanHost(host).Length > 0)
{
string workstationaccount = string.Empty;
if (host.IndexOf('.') == -1) // Pick which account to use, I have 99.9% success with this logic (only time doesn't work is when you run a interactive process as a admin e.g. Run As <process>).
{
workstationaccount = String.Format("{0}\\{1}$",StringHelper.GetAppSetting("DomainName"), host).ToUpper();
}
else
{
workstationaccount = String.Format("{0}\\{1}$", StringHelper.GetAppSetting("DomainName"), host.Substring(0, host.IndexOf('.'))).ToUpperInvariant();
}
account = users[users.Length - 1].Equals(workstationaccount) ? users[0] : users[users.Length - 1];
domain = account.Substring(0, account.IndexOf("\\"));
user = account.Substring(account.IndexOf("\\") + 1,
account.Length - account.IndexOf("\\") - 1);
}
iu.undoImpersonation(); // Disable Impersonation
}
Now using the account we grabbed in the first function/process, we now try to verify and decide if we should show a login or auto-login the user.
MembershipUser membershipUser = Membership.GetUser(user);
if (membershipUser != null && membershipUser.IsApproved)
{
string userRoles = string.Empty; // Get all their roles
FormsAuthenticationUtil.RedirectFromLoginPage(user, userRoles, true); // Create FormsAuthTicket + Cookie +
}
I wrote a blog post about this a long time ago, here is a link to the wrapper for netapi32.dll and my Impersonation helper that I provided in the post Source Code Download
You cannot have both NTLM and FormsAuthentication in the same ASP.NET application. You will need two different applications in separate virtual directories.
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.