I'm developing a website in ASP.NET and C#.
I've created the website so when a user goes to the site, his windows client username is read out with:
System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
and then I lookup his username in the db and create a user object with all necessary data (team, name, permission level, role, ...) from the return data.
Then I keep this object in a session var until the user logs out.
This was working like a charm locally but now that I've deployed to the server I get defaultAppPool for every user.
What am I doing wrong?
In my web.config file I have:
authentication mode="Windows"
I have to admit this is the first time that I'm doing the deploying myself and everything went smoothly except for this.
As you've discovered, System.Security.Principal.WindowsIdentity.GetCurrent() gives you the identity of the application pool.
You should be using HttpContext.Current.User.Identity.
Windows authentication and IIS
If you select Windows authentication for your ASP.NET application, you also need to configure authentication within IIS. That’s because Windows authentication is delegated back to IIS. IIS gives you a choice of four authentication methods:
If you select anonymous authentication, IIS does not perform any authentication. Anyone is allowed access to the ASP.NET application.
If you select basic authentication, users must provide a Windows username and password to connect. This information is sent across the network in clear text, making basic authentication dangerously insecure on the Internet.
If you select digest authentication, users must still provide a Windows username and password to connect. However, the password is hashed before being sent across the network. Digest authentication requires that all users be running Internet Explorer 5 or later and that Windows accounts be stored in Active Directory.
If you select Windows integrated authentication, passwords never cross the network. Users must still have a Windows username and password, but either the Kerberos or challenge/response protocols are used to authenticate the user. Windows-integrated authentication requires that all users be running Internet Explorer 3.01 or later.
Get current user identity as :
var userWinId = HttpContext.Current.User.Identity as WindowsIdentity;
Use
System.Web.HttpContext.Current.User.Identity.Name
instead of
User.Identity.Name
or
System.Security.Principal.WindowsIdentity.GetCurrent().Name
Related
Our all libraries and application use forms authentication, so it is necessary to use it here.
The application is hosted on IIS with below settings:
anonymous authentication: enabled
forms authentication: enabled
windows authentication: disabled (this must not be changed)
This returns the user under IIS runs (in my case IIS APPPOOL\tdm)
string userName = System.Security.Principal.WindowsIdentity.GetCurrent();
string userName = Environment.UserName;
In web.config:
<authentication mode="None" /> //(this again must not be changed)
Is it possible somehow to take the Windows credentials of the user who uses the application?
My job is when someone enters the app to log in with this credentials automatically, but for that, I must find a way to take his Windows user account.
I don't think that what you are asking for is possible within a standard webforms framework. You cannot automatically get a browser to send the windows credentials without enabling windows authentication.
If the application is hosted on the same domain, it is relatively easy to use standard forms authentication with an existing AD username/password - also called Single Sign On.
When you enable Windows authentication in an application, and then make a request from a browser, it actually returns a 401 - Unauthorized status code. The browser then decides based on your settings whether to send your identity in a second request. This may happen automatically, or it may prompt for credentials.
I have viewed and tried dozens of "answers" on StackOverflow, but none work.
I have a pretty simple aspx page with C# code behind.
The web site is on a Windows 2008R2 server.
The web site looks like (actual names changed):
MyServer - set for Anonymous Authentication
Application Pools
ASP.NET v4.0 Classic - .Net 4.0, Classic pipeline, App Pool Identity
MySiteAppPool - .Net 2.0, Integrated, runs under a Domain-wide Service identity (call it "mycompany\domservice")
Sites
MyMainSite - Windows Authentication, uses "MySiteAppPool"
"AutoPrint" - my web app, Windows Authentication, uses "ASP.Net v4.0 Classic" app pool, ASP.NET Impersonation enabled
My "AutoPrint" web app has a start page "AutoPrint.aspx" and code behind ("AutoPrint.aspx.cs", plus several classes).
The server and main site are not alterable, as there are several other applications under this site.
The user currently invokes this app with :
http://MyServer/AutoPrint
Everything I have tried is returning the "mycompany\domservice" result:
Request.LogonUserIdentity.Name.ToString() - returns "mycompany\domservice"
System.Environment.UserName.ToString() - returns "domservice"
System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString() - returns "mycompany\domservice"
What am I missing here? Why is this so hard?
Further clarifications:
"mycompany\domservice" - the "domservice" account is just an ActiveDirectory account in the "mycompany" domain that has permissions to read/write directories needed by the site and other applications. When installing the Site and additional web apps, we use that account as the "connect as" user.
What I am trying to do is to get the ActiveDirectory name of the Windows user account of the person who opened their browser and accessed this app. If user "JJONES" logs into Windows and launches the app with "http://myserver/autoprint", I want to get either "JJONES" or "mycompany\JJONES" as the user name.
If you use anonymous authentication, then the browser does not send any credentials (user id/password) to the server. Therefore if you want the client user id on the server, you have to use non-anonymous authentication, e.g,. Windows or Forms. You can use non-anonymous authentication and then allow or deny access to your web site to specific users or groups of users, or all users.
Thank you for all the helpful comments/suggestions.
The problem turned out to be a combination of factors. The App Pool I was using was using App Pool Identity (which has limited rights), so I had to use a specific account (the domain service account) in the "Connect as..." for the physical path credentials in order to access certain files.
Changing to use an App Pool that used an account with sufficient privileges (the domain service account) allowed me to leave the "Connect as..." using Pass-through authentication when converting to application.
Voila - I now get the user credentials using pretty much any of the proposed methods. After way too many hours of beating my head against the keyboard...
Have you looked at using HttpContext.User property ? This will give the current logged on user. After which point you may need to perform some nifty LDAP queries to get the username from AD.
See https://msdn.microsoft.com/en-us/library/system.web.httpcontext.user(v=vs.110).aspx
You may want to see the below link on how to search AD on the link "How can I search Active Directory by username using C#?"
Hope this helps you.
Is it possible to grab a users windows credentials (i.e. username) without having windows authentication enabled in IIS? With windows auth disabled the code below returns either NT AUTHORITY or IIS APPPOOL\ASP.NET v4.0 depending on if impersonation and anonymous authentication are enabled or not.
System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
I am converting an asp.net web application that is using forms authentication to custom authentication. Basically if a user is connecting from outside the network I force a credential check whereas if they are connecting from within the network I would like to be able to just grab their windows username. The internal portion works when I turn on windows authentication but I get the popup login box when testing outside of the network. I either need to disable windows authentication for non local connections or figure out how to get the windows username with windows authentication disabled. Any suggestions? (The other alternative i thought of was splitting the application in two and having separate authentication modes for each but I'd like to avoid this).
-I have also tried:
System.Web.HttpContext.Current.User.Identity.ToString();
System.Threading.Thread.CurrentPrincipal.ToString();
something like this is actually (kind of) possible using Active Directory Federated Services. In the event of a windows user from inside the network they can be configured to use their account details. For external users, they can be redirected to a page that will require them to log in.
However. This is very heavy-duty and an extreme pain in the..neck to implement and is really only applicable to enterprise solutions that have the resourses to use this kind of solution. Otherwise, I'd say go with the 2 site approach.
Simple answer is no.
Best solution is to create 2 sites. One for internal users that user windows authentication, one for external user that user forms authentication but authenticate against AD. You can make users always go to external site by default and then redirect based on their IP. That is redirect intranet users to internal user.
I want to get the client window username with which the user is logged in on their machine,
I have tried these:
Request.servervariable["LOGON_USER"],
Request.servervariable["AUTH_USER"],
Request.servervariable["REMOTE_USER"]
but when I deploy my application on IIS the values of all these are blank,
some constraints are applied for my app senario: I am using the authentication mode ="form"
because I am passing the Windows account username to db, then I'm authenticating if this Windows user id is present in db.
Similarly I want anonymous access in IIS.
Assuming you've enabled windows authentication, Page.User.Identity.Name should give you that!
We are implementing the following log on mechanism for our 3-tier application:
User launches the client application and -
authenticates using her Windows session credentials (Active Directory)
or enters her AD credentials if another user is already logged on to this Windows session
or enters her user name and password if the computer is not on the AD domain.
I.e. something like the SQL Server Management Studio log on box (+point 2. above).
The solution we came up with is having two endpoints, with two system bindings (one with Windows, the other with UserName client credential type).
I was wondering if there's a way of having just one endpoint with a custom binding that would magically allow the mixed authentication (either Windows or UserName)?
Also, why is it a bad idea?
Thanks!