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.
Related
I am currently working on a project that has a requirement that is causing me some issues and I want to know the best way of handling it.
Essentially we would like internal users to be able to access the MVC application and be authenticated through AD, this we want to be pretty much like SSO, they sign on to their computer navigate to the site and they are in.
The second type of users are outside partners that do not exist in our AD and we want to manage through our SQL Server. For these users we want to display a login page and do forms authentication.
My thoughts at first were simple, let IIS try and authenticate with windows authentication and if it fails (401) redirect to a login page. I don't currently have an environment to test this in but from my understanding in IIS7 it is not that simple and requires a little bit of a "hack" to accomplish. I need to avoid anything like that I need a solution that works as the system was designed to work and not by tricking it.
I have looked into ADFS and WIF but ADFS only supports AD not SQL and from what I've seen there is no STS that supports SQL Server. I have contemplated hosting both an internal application that used windows authentication and external application that used forms authentication but I want to avoid this if possible.
Ideally the flow that we want is user navigates to the MVC application IIS tries to do windows authentication, if it fails (401) redirect them to the login page. From there the login page will authenticate the user credentials against the SQL Database. What is the best way of accomplishing this all within 1 MVC application?
Thank you!
I would just implement my own authentication on top of FormsAuthentication or OWIN if you are using ASP.NET MVC 5. It is really simple and you will have full control over where you go to authenticate users. Trust me it isn't as scary as it sounds. I've written a few posts about it that you might find interesting.
MVC 5
http://www.khalidabuhakmeh.com/asp-net-mvc-5-authentication-breakdown-part-deux
MVC 4
http://tech.pro/tutorial/1216/implementing-custom-authentication-for-aspnet
I currently use the MVC 4 method to authenticate against an Active Directory domain with great success. The only thing I would recommend is you Cache your calls to Active Directory as it can be unreliable at times.
There is the STS that supports sql server, it is the IdentityServer.
https://github.com/thinktecture/Thinktecture.IdentityServer.v2
It even supports custom membership providers which give you quite a lot of different possibilities. I am not sure however if it supports automatic fallback to forms when integrated authentication fails. If not, there are two options: a custom sts or two explicit stses and an explicit choice for users. We have implemented the latter scenario once with ADFS - there were two adfses, one with Forms, the other one with integrated auth, first one federated with the other. This gives an explicit choice on the home realm discovery page - ".would you like to log in with username/password or try the integrated authentication"
You could create a project that uses "On-Premises Authentication" which uses ADFS to authenticate users. The on-premises authority URI will be:
https://yourADFSservername/federationmetadata/2007-06/federationmetadata.xml
After your project is loaded, you can to goto your ADFS settings and create a new "Relying Party Trust" and pass on HTTPS URL that your MVC app will be using. Setup to used LDAP attributes as claims and that will sort out AD authentication easily as it will navigate users to organisational sign-in page just like Office 365. Then if authentication fails for certain users, take the user to send the user to normal sign-in/signup page that exists independently of AD and connected to SQL server. You could skip windows authentication altogether by using on-premises authentication.
So I have done a bit of research on the matter. According to this link:
http://technet.microsoft.com/en-us/library/bb232199(EXCHG.80).aspx
In the "Permission for using Outlook...." section it says:
To use Outlook Web Access Web Parts, you must, at a minimum, be delegated "Reviewer" access to the content that you are opening. If you have embedded an Outlook Web Access Web Part that requires authentication into an application, you must pass authentication information through together with the request for the Web Part. One way to do this is by configuring the Outlook Web Access virtual directory to use Integrated Windows authentication. Integrated Windows authentication lets users who have already logged on by using their Active Directory account use Outlook Web Access without having to enter their credentials again.
The sysadmin here does not want to do that since the fallback (if there are not on the right domain and auth fails) for having OWA use integrated security i guess sends a form with the password in plain-text. According to him, have not researched yet.
I have an asp.net MVC4 intranet application in development, and it is using windows authentication. So two questions:
Is there are way to pass credentials to the iframe without messing the the exchange server setting?
If so, how can I do it?
I lied, three questions:
/3. If I had the exchange setting to allow integrated windows auth, and I try to hit the site from a different domain that is not authorized, how does it fall back to a login form, and is it really a security risk?
Here is the iframe code:
<h2>Inbox</h2>
<iframe
src="http://server/exchange/user/?cmd=contents&fpath=inbox"
width="100%"
height="300"
sandbox="allow-scripts allow-same-origin"
seamless
frameborder="0"></iframe>
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'm writing an web application (in C#) where I need to logon to a web page using different credentials to the user logged on locally to Windows. That page the executes a process on the web server but it executes as the user that has logged into the web page. The user logging into the web page is authenticated against Active Directory. I've used Windows Authenication and ASP.NET impersonation to launch processes on the web server, and I can create a site that uses forms authentication against AD, however I can't find a good article that explains how to run a process impersonating a user that have logged on using forms authentication from AD. Whenever I run anything it just give me an error because it's trying to run as 'NT AUTHORITY\IUSR'. Does anyone know of any good articles, or can you give me any code examples?
Thanks in advance,
Rich
take a look at ProecessStartInfo - you can setup security etc. (if your thread is already running impersonated then you can get some of the necessary info from System.Threading.Thread.CurrentThread /CurrentPrincipal) and then call Preocess.Start.
I have the following scenario where I’m planning in using windows authentication.
1.1) I have a web server which will run within a domain.
1.2) The web site will run under the credentials of a domain user with a set of configured permissions (One which will be allowed access to the file system, SQL server database etc).
1.3) Users visiting the web site will belong to the same domain, so I’m planning in using windows authentication.
So at this point, an authenticated user, would access the site, but I guess that from code, “CurrentUser” would be the one under which the site is running.
I’d like the following.
2.1) To authenticate the user accessing the site with windows authentication. (Domain controller would be responsible for this).
2.2) For the site to run under the configured user from step 1.2. So it would have all of its permissions.
2.3) But I’d like to know the initial user used to authenticate from (step 2.1).
This way I could do the following:
3.1) User “A” decides to access the site, as he belongs to the same domain as the web server, he authenticates successfully.
3.2) From code I detect that “A” authenticated, so I’ll go and fetch his roles. “Role1, Role2, Role3”.
3.3) I then want the code to run under the user configured in step 1.2, but I’ll assign the Principal all of the roles retrieved from 3.2.
I’ve thought that maybe I could use Impersonation for this.
4.1) So user “A” decides to access the site and authenticates.
4.2) The site would initially run with “A” credentials, so the “CurrentUser” would be “A”.
4.3) Switch the user (somehow) back to the one from 1.2
4.4) I could retrieve all of 4.1 configured Roles.
4.5) Assign the Current Principal the roles retrieved from 4.4.
So in the end the web site will use Windows Authentication with Impersonation, but from code I’d switch back to user 1.2.
If you’ve reached this point thanks for reading! I’d like to know if this is possible and if it seems achievable or if I’m overcomplicating things.
Also suggestions in how can I plug into and where to do all the role retrieving and user switching.
Many thanks!
UPDATE 1
# Code Jammr , you're right, no need to do any crazy stuff. But I think I still need to look into HttpModules,..
After doing a few tests, searching etc...
I've started to understand the difference between these IIdentity objects:
HttpContext.Current.User.Identity
Thread.CurrentPrincipal.Identity
WindowsIdentity i2 = WindowsIdentity.GetCurrent();
I posted another question to help me understand them:
Help understanding impersonation
I think this answers my question.
There are several code samples out there for doing Impersonation. Most involve dealing with tokens and Win API calls. But if you really must do it this way, I say this not knowing what your webserver type is. IIS 6 or IIS7, then there are many code samples out there to guide you along.
Here is one link for ya that pretty much gives you a starting point.
http://msdn.microsoft.com/en-us/library/aa331755(v=vs.71).aspx
Here is a link on AD authentication and you may not have to do anything crazy.
http://support.microsoft.com/kb/326340
You may want to look into asp.net impersonation, app pool settings, etc... to see if there is a better way.