We've built an internal ODATA API that is hosted on IIS. It's been up and running for some time and everything works as expected.
Now, I have a specific application (Tableau Desktop) that needs to connect to some of the ODATA API endpoints. Tableau Desktop can't use Windows authentication when connecting to ODATA (I'm aware that Tableau Server can), so I thought I would look into a way to override the default authentication.
My problem is this: IIS, being the host, controls authentication to all endpoints using Windows authentication. I want to override the host authentication to allow a user to connect to Tableau using Basic authentication on specific endpoints.
If Windows authentication is enabled at all, it overrules any attempts I make to force Basic authentication.
Is it possible to turn off Windows authentication for specific endpoints/controllers?
I tried doing it by adding these tags, but it doesn't work:
[OverrideAuthentication, OverrideAuthorization]
[Authorize, IdentityBasicAuthentication]
public class ProjectTrackingController : ODataController
The IdentityBasicAuthentication tag is a custom authorization component I put together to check basic credentials. This custom component gets hit every time I make a request, but even though I type my credentials into the browser/Tableau, the request gets passed along with the "Negotiate" header that appears to have a key for Windows credentials. There never appears to be an attempt at authorizing the HTTP request with Basic auth.
There does not appear to be a way to override the parent level authentication as it stands. Since we are authenticating with IIS, the code cannot override the NTLM authentication required by IIS. Even though I added tags for Basic authentication, IIS restricts this at the top level.
We are going to switch to HTTPS (which needs to be done anyway for better security) and then enable Basic auth in IIS rather than NTLM. This should resolve the current issues we are seeing when connecting Tableau.
I have already developed front-end application in Angular2 and back-end in ASP.net web APIs. I had used Windows authentication as enabled because I want to detect requesting user. Both applications are hosted in IIS server(Windows Server 2012).
When I load angular app it load login prompt and when give correct user credentials data loading happen correctly.
But I want to know a way to load them without login prompt, authenticate automatically.
This is the way I detect request user in web APIs.
string user = HttpContext.Current.Request.ServerVariables["LOGON_USER"]; //Get the current user...
userID = user.Split('\\')[1];
This is a sample TS script send request to Windows Authenticated Web APIs from Angular Services.
getPersonalInfo(): Observable<IPersonalInfo> {
return this._http.get(localStorage.getItem('WebApiURL') +"api/PersonalInfo/" , { withCredentials: true })
.map((response: Response) => <IPersonalInfo>response.json())
.catch(this.handleError);
}
When restart the browser this login ask every time.
I want to access them with out this login...
Actually, this login prompt occurs because there is communication between two technologies (ASP.net & Angular 2) by passing windows windows credentials. So it need shake-hand authentication when call windows authenticated API.
I was lucky to find a solution by changing privacy settings through browser. So I got ability to call API's without login prompt.
Here is the way to do that.
Settings -> Open Proxy settings -> Privacy ->Sites
In here you can add domain where your back-end APIs are already hosted as in example.
After that it take as trusted domain and further more there is no any login prompt accruing.
I have spent a lot of time on this, and I'm not sure it can be done. If you enable Anon Access then the [Authorisation] on the controllers works fine. But you can't detect the username.
If you disable the Anon Access then you can obtain the username NETWORK//USERNAME but if you access a method with the [Authorize] attribute then you get the popup dialog you have got.
I really don't want to go back to a username/password solution but it is looking like I am going to have to.
I have tried my best to search the web before asking this question. I've seen similar questions on stackoverflow, however, none has been answered satisfactorily for a long time now. This is one more attempt to get this recurring question answered.
The Problem
How to build an ASP.NET MVC 5 website which uses "Windows Auth" for Intranet users and "Forms Auth" for Internet users? We'd like to accomplish this using ASP.NET Identity. Moreover, we don't want to use Active Directory Groups for authorization. For Intranet users, we want to authenticate them using Active Directory and then fall back to ASP.NET Identity to manage their roles and other profile data.
It'll be nice if we don't ask the end user to choose auth method. The web app should log in intranet users seamlessly. They shouldn't even know that there is a login screen. Likewise, the internet users shouldn't be asked to enter their domain credentials. They should see form based login screen right away.
Is there any recommended way of solving this? Or could you comment if any of the following are proper solutions?
http://world.episerver.com/blogs/Dan-Matthews/Dates/2014/8/Mixing-Forms-and-Windows-Authentication/
https://github.com/MohammadYounes/MVC5-MixedAuth
http://mvolo.com/iis-70-twolevel-authentication-with-forms-authentication-and-windows-authentication/
FYI This is 2004 article, may not be helpful now:
https://msdn.microsoft.com/en-us/library/ms972958.aspx
IIS configuration
Enable Anonymous Authentication status in IIS for the whole site and Windows Authentication for some folder under root directory (for example, /WindowsLogin). In this folder place aspx file (for WebForms project) or create ApiController (for MVC project).
Site setup
On login page add button “Login with Windows/ActiveDirectory account” (in similar way as it is common practice to add buttons Login with Twitter, Facebook, Gmail, etc.). When user presses this button, they will be redirected to the page or controller in /WindowsLogin folder, which require Windows authentication. If site uses some Single Sign-On functionality, locate it in that page or controller, in other case just save Session for Windows users there. If user accessed that page or controller, they had been authenticated as Windows users already.
One of the possible ways could be creating two sites in IIS, but having the same target folder, where sources of site are located. First site is for internal users with enabled Windows Authentication mode and binding to 80 port, while second site is for external users with Anonymous mode enabled and binding to 8080 port, for example. Then, on firewall you will have to configure NAT, that all requests coming from within local network or VPN, will be redirected to local IIS server on port 80 and all requests coming from Internet, will be redirected to port 8080 of IIS server.
The term for this is Mixed-Mode Authentication. I have done this multiple times. You only need to tweak your main site. Here is how I have done it.
Keep your main MVC site as-is but run it as Anonymous vs. under Windows Auth.
Internal Site
Create a Redirect URL Site: Setup this site as Window Auth so you can pull the User ID from Active Directory. Give your users this URL and/or make it the link they click on your Intranet. Then this site calls your MVC Site and passes the user credentials (login id).
a. This can be done either via an encrypted string on the URL or encrypted value in a cookie. You can encrypt with an expiration date/time value too.
b. (Speaking from Forms Auth) Create a Forms Authentication Ticket with that user ID. Run any other login logic you have. Done.
External Site - No Changes required. Let the users login as-is.
Are you wanting to handle forms and AD authentication from one URL? I have used thinktecture (claims based auth) as the framework for WIF and marshaling various forms of authentication. However to handle if from one URL I had to handle some logic at login that associated the user to AD or Forms based. In a more recent project, this was handled at user management when we created the user account (it was associated to AD of Forms Auth). Then when the user logged in they would preface the AD domain name as part of the login. There are a number of ways to implement this, this was just one I have used. An example, instead of requiring the domain, just use the username, then check for AD or forms based flags on the username and then handle authentication accordingly
EDIT
Just an update in re-reading your question. Are the internet users and intranet users the same? If so you need to just go forms based auth across the board and manage the users in the product DB independent of AD. If they are the same then they could login prefacing the domain name to username. if you wanted to rely solely on AD.
I did a proof of concept of this some time ago, at my previous job, so the details are hazy and I don't have any code to refer to...
The requirements were:
Single URL for internal (LAN) and external (internet) access
Two types of users, people on the domain and external (non-AD) users
Windows authentication for domain users both internally and externally
The ability to enter domain logon details when using iPads (no windows auth)
The core idea in the solution I came up with was that we used Active Directory Group Policy to add a custom string to http request header user agent, the content doesn't matter, in fact we used a long random string of characters.
https://technet.microsoft.com/en-us/library/cc770379.aspx
Then the landing page for the site checks for this, and if found redirects to a virtual directory, with windows auth, that checked their AD account, populated the ASP.NET authentication token and then redirected them to their home page.
If the custom header isn't there then it just displayed the normal login form.
The only other thing was to add an AD email/password check to the normal login form so that if a domain user accessed the site from a non-windows device (iPad) then they could use their normal login details.
Why not put your website code on the server, robocopy it to two separate websites and just handle the changes in authentication by configuring the web.config. (one would be setup with anonymous and one with windows authentication.)
It's not as snazzy as other methods but it's relatively painless. There are two sites but the content (except for the web.config) are identical.
I have an ASP.NET 4.0 WebForms site that is running on a IIS6/Server 2003 instance. The site itself does not permit anonymous access and uses IIS basic authentication before the user can get to the Forms authentication screen. However, there are two site nodes below the site level, that are virtual directories which DO permit anonymous access (for requesting static images by other machines).
A new request required me to route those requests to a different page and examine the URL being requested and perform different tasks. I’m using a MapPageRoute method in the Global.asax file and the route clears through Forms authentication with a web.config setting <allow users="*" />. Obviously, that works great locally, but when deployed to the IIS6 machine basic authentication kicks in before the request gets routed.
Is there a good way to "fake" or create a virtual directory node in IIS6 and grant it anonymous access so that the routed url request can execute?
This might not work for everyone, but since in my case HTTP Authentication was primarily instituted just to prevent people from multiple attempts at the login page, I actually removed Basic Authentication from the site and all virtual directory nodes.
Then I added it just to the ~/[loginpage] that was being used. Since forms authentication was in use all unauthenticated users are re-directed to the login page and then get the basic authentication. Since the routed page request needed to be public I just added it as an exception to the Web.config. The routed values have to meet a very strict criteria to even be executed by the page logic and everything else is returned as a 404 by the handler.
Obviously this means that the asp.net dll is executing before IIS basic security when requests are redirected to the login page, but in this case I think it is fine.
I have an ASP.NET site on a public web server, where users login using forms authentication.
I would like users within certain organisations to be able to login automatically through Windows authentication (bypassing the login page). However, because these clients are on lots of different servers, I can't just build in Windows security to the main site. (I know there are articles on how to mix Windows and Forms security.)
My idea is for each organisation to install a page onto their intranet which redirects to my website and authenticates the user according to their Windows domain and username. Is this possible to achieve securely? How could I go about doing it?
What you have described is almost federated identity.
As well as a page on each site, you will also need a webservice whch will validate a token.
Essentially the flow is:
User comes to your logon page
you redirect them to their company logon page
their company logon page takes their credentials and redirects back to you returning a token
you then call their webservice to validate the token an determine who the user is.
Many public API's use this scheme (facebook being a notable example).
look up oauth and federated identity for more information.