We have a vendor app that uses windows authentication to pass windows credentials from their MVC app to a web browser control that is pointed at a internal site. This provides a SSO-like experience from the app to the IIS session.
We want to publish the IIS site on the internet and the external/non-domain user must be automatically authenticated in our domain out on the internet. We don't want to put a domain controller in the DMZ. The vendor app is a compiled c#.net site. They will log into our portal site with a simple username and password. This set will be the same for an actual AD user. We want to turn their simple login into a windows authenticated "session" so that when we redirect them to the vendor app, their app will see that they are (somehow) an authenticated windows authentication user and simply pass them on through. (Providing them with a SSO-like experience).
This works if you are on our network and logged into the domain, but these will be non-domain users out on the internet.
Related
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.
I have a single sign-off requirement from our customers as part of our next release. The existing flow is as follows:
User logs into their organization system (ad user) or main portal system using their email ID or user name as provided by the organization.
User clicks the link to my web (i.e. angular + web api)
User is automatically taken as a logged in user and he can access protected pages. If the user wants to log in from outside the organization he must use the login form on our site.
I have completed the login form web application using the email/password that we have stored in our local system, but I am still struggling to implement with window credential's.
My project is based on web api 2.0 with an angular fronted. It's hosted on IIS. I don't want to use any 3rd party DLLs to manage everything, so are there any appropriate solutions available in the .NET environment which would achieve my requirements in a simple way?
If your website needs to seamlessly authenticate user credentials in an AD domain, one way to achieve this is by creating a small IIS server with NTLM authentication inside the domain and forward some type of authorization/credential key to your outside website.
My team tries to setup an intranet portal powered by Umbraco which requires Windows Authentication for authenticating its users that are stored as (Umbraco) Members.
Currently we have done the following:
In the Authentication Feature of IIS, we enabled only Windows Authentication at the root of the web site (all other authentication options are disabled).
In Web Config, we changed the Authentication settings mode attribute from Forms to Windows.
The username of the Members is stored in the domain\username format.
That works fine as far it concerns authentication and authorization of members in the front end. But in the back office (that requires Forms Authentication), it does not work well with the above settings, as sometimes the browser displays the authentication popup window and requires for the back office user to enter his (domain) credentials or sometimes randomly terminates the back office user's session and logs user out.
Is there any suggested way for implementing Windows Authentication for Umbraco portals that does not raise such issues in the back office?
Any help will be greatly appreciated.
Our client requested from us to make our web application accessible from Intranet and Internet.
When user tried to access the website from Intranet, The user should be logged in immediately (Windows Auth) ... The user should have public access also (e.g. Home, Coffee shop), But in this case he should use his credentials and the server will check if its valid.
Any advises?
This is the standard way Integrated Windows Authentication works. If you're inside the intranet (logged onto the domain), IE will automatically send your credentials when the website returns 401.2 (no auth method specified). When you're not inside the domain, the credentials will have to be prompted for, since the domain server cannot be contacted from the client machine.
This is not the same as the "tricky" solution you referred to. That solution is tricky because it also uses forms authentication, which you don't need here (AFAIK).
We decided not to use Windows Auth at all.
The customer want to stay logged in if he is in the Intranet.
so we did the following (and the customer is ok with that)
Forms Auth + 'Keeps me logged in' checkbox
Validate Credentials with AD.
Check if User in trusted IP Addresses Range (Something like allowed IP addresses in SQL Azure)
If trusted IP Range, user becomes authenticated.
If its not, Two factor auth by sending SMS.
One more reason for not using Windows Auth.
The user want to log-out at anytime to use different credentials to do some special tasks.
Usually customers do not know what exactly they want, so we will start dreaming and make things complicated. 'Simply keeps me logged in' for trusted IP addresses and he will stay logged in for N days.
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