Reverse proxy and ws-federation adfs 401 issue - reverse-proxy

We have a couple of back-end web applications to which we want to provide access via the public internet. To that end, we are setting up a reverse proxy (IIS 7.5) from our DMZ. At the same time, we want these web applications to be claims-enabled through ADFS 2.0.
WEB1.MYCORP.COM/WFE1 is the other back-end web application, on our internal network
WEB1.MYCORP.COM/WFE2 is the other back-end web application, on our internal network
ADFS.MYCORP.COM is the ADFS 2.0 server, on our internal network
FSPROXY.MYCORP.COM is the ADFS 2.0 proxy server, on our DMZ
RPROXY1.MYCORP.COM is the reverse proxy for WFE1, on our DMZ
RPROXY2.MYCORP.COM is the reverse proxy for WFE2, on our DMZ
In keeping with the proper configuration of ADFS, our internal DNS resolves ADFS.MYCORP.COM to the actual internal server, while external DNS points ADFS.MYCORP.COM to the ADFS proxy (FSPROXY).
So, here's the scenario:
End user browses to RPROXY.MYCORP.COM
Reverse proxy forwards request to WEB1.MYCORP.COM/WFE1
WFE1 redirects browser to ADFS.MYCORP.COM (actually FSPROXY)
ADFS Proxy prompts for credentials and authenticates against ADFS server
Upon successful authentication, browser redirected back to web app
I have a couple of questions. Do I need to configure something in the rp or the application to allow this. Also the adfs endpoint is the rp url is that an issue?
Do I need to set up something for the reverse proxy as well? (Should I/can I) set up a claims-enabled reverse proxy in IIS? How do I set up the reverse proxy rules to pass back the ADFS request unaltered? Currently, when I try to access the back-end application, it fails with a 401 authentication error. If I remove the proxy and just hit the app server it works fine.
Further,
This fails:
The path is client --> rp -->app -->adfs --> rp -->app --> rp -->client machine
this works:
The path is client -->rp -->app -->adfs -->app -->rp -->client machine
Any suggestions would be greatly appreciated!

Not familiar with how you enabled reverse proxy in IIS (ARR?). Something like this http://blogs.iis.net/carlosag/setting-up-a-reverse-proxy-using-iis-url-rewrite-and-arr
One choice for you is to use ADFS 2012R2 (if possible) because the proxy in that, the Web Application Proxy, handles both ADFS authentication and can handle app publishing for your claims enabled application. There are 2 ways you can publish your app to the internet. Once is pass-through which is kinda what you are trying to do. But it also allows pre-authentication support for a claims aware app. This way, you can have a different policy that decides whether the application can get pass your EDGE network before a packet goes to your internal application.

After doing lots of digging and fiddler traces I found the issue. In testing idp setup the token was different then stage env. The fiddler traces showed that the token was making it back to the app server. The issue was it also looked like the cookie dropped off for no reason. The issue was because the old dev ipd value disagreed with the stage value...naturally. Once I cleared the old token from the database everything worked.

Related

Conditional Https Redirection with .Net Core based on the Url

I have a Website that runs on a web farm (4 servers) behind a load balancer. The load balancer is the one that has the ssl certificate for https and decides to what server the requests go to.
In the code for the website, using .net Core I have in the startup.cs file logic in the Configure method to force the https redirection with app.UseHttpsRedirection(); So when we access the site without https the .net core permanent redirect the user to the https version (this is importand bc the web app is a PWA, so we need it for use service worker)
Imagine the url to access the website is https://production.website.com, again if the user try to go to http://production.website.com, it will redirects to https version. But you can also access each server in the web farm directly using these subdomains http://prod1.website.com, http://prod2.website.com, http://prod3.website.com, http://prod4.website.com (we have this set bc we want to test individual servers in case a deployment error happens on a specific server).
The problem is, bc the ssl certificate is in the load balancer (production.website.com domain), when you try to go directly to a individual server (prod1, prod2, prod3 or prod4) the .net core will redirect it to the https version and that server doesnt have a ssl certificate and the user will see an error on the browser, so we need a way to control that with a condition. So what the problem is? that at the startup.cs code we dont have access to the site url bc we dont have a request yet, I have research a lot and some workarounds that use to work in the past now with .net core 3.1 dont.
So how I can make that the code in the configure method doesnt force a https redirect if the users is accessing the individual servers and not the main domain for the web site?

Blazor Server Reverse Proxy with Authentication

I have a blazor server-side application (netcore 3) which uses authentication through OpenID / Okta.
I started testing it through IIS, and running it as a regular website worked just fine.
But, I need to run it through a reverse proxy due to the rest of our setup, and after I set that up the blazor site no longer functions.
Our reverse proxy is simple, just takes a url (https: //subdomain.domain.com), and routes it internally (http: //localhost:8093). There are other sites connected here, this was just an example.
I managed to get all the resources (css, js, images) working correctly by adding the "app.UseForwardedHeaders", but I am still having an issue with Authentication.
For Authentication, it's setup with services.AddAuthentcation, and AddOpenIdConnect, which is triggered by an MVC call to Account/Login, that issues the HttpContext.ChallengeAsync.
Running the application standalone, or in it's website, the Login works, and redirects to Okta (https: //oktadevurl.com/oauth2/default/v1/authorize?parameters).
Through the reverse proxy, this url becomes relative to the Proxy address (https: //subdomain.domain.com/oauth2/default/v1/authorize?parameters) which is incorrect.
I've double checked the forward headers, and OpenId / Okta settings. I'm looking for anyone who has had this issue before and could point me in the right direction on how to get the absolute urls working from blazor through the reverse proxy.
Thanks.
I was able to solve this with one little checkbox is ARR:
In IIS Manager, Select the current server (not the website), open Application Request Routing, and on the right hand column there will be an option Server Proxy Settings. There you will see "Reverse rewrite host in response headers" option. If that is checked - uncheck it and your problem should be solved.

How can I authenticate a websocket connection where client and server reside on seperate domains?

I'm currently playing around with SignalR and websockets. From my research, it seems, as websockets do not support custom headers, there's basically only two ways to authenticate a websocket connection during token based authentication.
1) Passing the token in the query string
2) Storing the token in a cookie which then gets passed to the server when WithCredentials is set to true
The first method isn't great practice - even through websocket communication is encrypted, query strings may be logged by servers etc.
The second method I have got working on my local machine but it doesn't work once deployed because my client and server reside on different domains. So basically, I have an Angular site that has one domain (eg. client.com) and a WebAPI site that alls CORS with a completely different domain (eg. server.com). On my browser, if I'm on client.com, I cannot set a cookie that gets sent to server.com on a request.
What is a good way to authenticate websockets when client and server sit on different domains?
The WebSocket Protocol specification doesn't specify any particular way for authentication. You need to perform the authentication during the handshake phase and for that you can use any HTTP authentication mechanism like Basic, Digest, etc.
Further you could look into JWT token based authentication. Angular app can store the token in local storage and send it as a Transport header during the handshake request to the server. If the token is invalid, server can terminate the WebSocket connection upgrade request and the Angular app can re-direct the user to login page.

IIS removes Authorization header from the http request, when the request is from outside my LAN

I have an IIS 7.5 on Windows Server 2008 R2. It has the Basic, Anonymous and Windows Authentication modes enabled. I have hosted a restful WCF service in it.
I make an http request with Authorization header from my client within the LAN/VPN, all goes well. On the service side I could see that the OperationContext.Current.IncomingMessageHeaders contains the Authorization header with the right value.
When I attempt to do the same from outside the LAN/VPN, (I used a different Internet connection and also a public proxy), the OperationContext.Current.IncomingMessageHeaders seems to have missing Authorization header.
I am unsure as to what exactly removes the header. I suspect a misconfigured IIS. Any clues?
If you want your service to always do windows authentication as the question seems to suggest, remove disable all other auth modes in IIS, requests from LAN are passing probably because people requesting it are from the same domain, in an internet (putting this simply) will go for the least required auth mode, which in this case would be anonymous.

Error 407 when calling WCF web service via a Windows-authenticated proxy

I have the following setup:
Server machine running a WCF service exposed via an IIS application that requires Windows authentication.
A proxy server (Squid) requiring Windows authentication.
A client machine running a Windows service which tries to make a connection to the WCF service through the proxy server. The service is set with a domain account credentials.
All machines are on the same domain.
If I drop the proxy from the setup and set just the following properties on the client security binding, all works well:
SecurityMode = TransportCredentialOnly
Transport.ClientCredentialType = Windows
The connection is made successfully and the correct credentials are passed to the server.
If I add the proxy but drop the required Windows authentication on the proxy server, everything works fine too. The only setting I change here on the security binding is:
ProxyAddress = http://myproxyserver:3128
I can see the calls go through the proxy server with the correct credentials.
The problem is that when I set the Windows authentication requirement on the proxy server, the proxy server returns 407 error. When I check the log files, I can see there is no second attempt to respond to the 407 error with the correct credentials. The setting I add is:
Transport.ProxyCredentialType = Windows
Things I tried and didn't work:
Set UseDefaultProxy - since this is a Windows service, it doesn't accept the default proxy.
Manually set Windows Credentials in ClientCredentials.Windows (including domain).
Add default proxy in app.config and machine.config.
Any ideas on what's going on and how to fix it?
Two things that might be the problem. First, and I can not be sure about this as I have not tried using a Windows credential with TransportCredentialOnly, is that transport security tends to be point-to-point. That means that an intermediate service, such as a proxy, would have to authenticate your transport credential itself, as well as reestablish the appropriate credentials for its repeat of your request to the real endpoint. Again, I am not certain how this works with a Windows credential...but given that it is a transport-level security setting, I would be doubtful that it can pass through the proxy without additional setup to ensure the proxy repeats the appropriate credentials. (Keep in mind, doing so effectively nullifies your security at the proxy...which in a controlled setting is not a problem, but can be in a real-world scenario.)
Second, the transport child element of the security element for your binding configuration should have a proxyCredentialType setting. If your proxy is interfering with your security, you may need to authenticate against the proxy itself. The proxyCredentialType setting defines what kind of proxy credential to use to authenticate against the proxy itself. You would then need to supply proxy credentials before you send your message.