ARR 3.0: Client Affinity Not Working - asp.net

I have implemented HTTP Load Balancing using Application Request Routing for my web application. I have one Load balancer server and two application servers namely SERVER1 and SERVER2. I have configured the Client Affinity in my server farm in the load balancer server.
But the problem is that requests from same client are sent to different servers. This behavior I have confirmed in Monitoring and Management section in the server farm.
Also I am getting following error in the client "Object reference not set to an instance of object".
This is because When the first request from the client hit the SERVER1 it created an object in the session of the SERVER1. Now the second request from the same client trying to access the object created in session. But the request is hitting the SERVER2 from load balancer instead of SERVER1. As there is no session exists in SERVER2 client is getting this error.
I understand that Client Affinity configuration is meant to handle this problem where in all the subsequent requests from the client are going to the same server which served the first request.
But in my case this feature is not working. Any solution to this will be very helpful.

I found the solution ! The application was working fine with Firefox browser and not working with IE and Chrome. ARR uses a cookie to enable Client Affinity. The Cookie name will be used to set the cookie on the client. That said, the client must accept cookies for client affinity to work properly. Default cookie name is ARRAffinity.
To browse the application I was using the url servername/appname. ARRAffinity Cookie was not getting created when I am browsing the application from IE and Chrome. The cookie got created and the application was working fine when browsed the site using servername.domainname/appname

Old tread but may be useful for someone.
Seems that it's an ie issue or "expected behavior when using Internet Explorer": if a site name does not contain at least one '.' then the ARR Client Affinity cookie is not sent back to the ARR therefore the ARR generates a new one.
So, valid work around is any alias including '.' (dot) as Nagendra mentioned servername.domainname
http://forums.iis.net/t/1178295.aspx?ARR+2+5+Client+Affinity+Not+Working

Related

HTTP POST from app.example.com to localhost: session cookie not sent

I have two Spring Web applications that work together. I'm running the first application from the IDE on localhost, while the second one is running in docker on app.127.0.0.1.nip.io.
The two applications interact indirectly through the users browser by redirecting and POSTing between the two apps. This is slightly similar to how an SP and an IdP work together in SAML2.
In my case, the first application on localhost is sending a 302 to the second application. After doing some work, the second application sends an HTML page with a form an JS code to autosubmit it, back to my first application on localhost. The HTML looks similar to this:
<form method=POST action="http://localhost:8080/some/path">
...
</form>
My first application is using Spring Session with a session cookie, and this works just fine. However, when the second application makes the browser POST the form, the browser does not send the session cookie with the POST request.
When both applications are running in docker under .127.0.0.1.nip.io, the cookie is sent.
I've tried to find any hint if this behaviour is expected, and what headers or other bits the applications could use to influence this.
At this point, this is mostly an annoyance while debugging, but I'm concerned that once the two applications will run on different FQDNs and/or different domains, the browsers will also block the cookie being sent.
I've tested this with current versions of Chrome and Firefox.
The problem is the new(ish) SameSite cookie policy that covers exactly this case: another application is POSTing to a host via HTTP. The default now is SameSite: lax, which does not allow sending the first-party cookie values on this request.
The solution is to allow the session cookie to be sent by specifying SameSite: none. Be aware however that this might create security vulnerabilities. For my application, this is not an issue, so I can allow the cookie to always be sent, and especially when I run my application in the debugger.
For the production deployment, I will be able to tighten this, since both applications will run under the same domain (a.example.com and b.example.com), and both will use TLS, so I can set the session cookie to SameSite: lax.
Here's a decent explanation: https://web.dev/samesite-cookies-explained/

Saml ReturnUrl lost when proxy involved

I am using Sustainsys.Saml2 for authentication in my environment. It has worked well until I added a proxy into the loop.
The data flow is:
1) User navigates to site via proxy server (example.mysite.com)
2) Proxy forwards to internal application (example.internal.mysite.com)
3) Saml does its thing, forwards to service for authenticate and redirect
step
4) Weird part: The saml response is sent back to the original host hitting Saml2/Acs (example.mysite.com/Saml2/Acs) and responding as a 303 -- the assumption is that it should be 303'ing to example.mysite.com, but instead it's to the proxy host name at example.internal.mysite.com
Why is it doing that? It doesn't seem to be respecting the ReturnUrl (which is example.mysite.com). I see no evidence of the proxy URL from requests/responses during the auth process until #4.
The Sustainsys.Saml2 library builds various URLs from what it sees in the incoming HTTP Request. When a proxy is involved, that might not be the same URL as the client sees.
There's a setting PublicOrigin that you can set to handle this, that will override any host found in the request.
However, in The AspNetCore2 handler it is assumed that this has already been fixed in the Request object, before the handler is invoked. This is usually done automatically by the hosting environment if hosting in Kestrel behind IIS or similar.

Not always receiving client certificate in IIS

We have a ASP.NET web service which needs to receive a client cert from another service. We have configured our cloud service in IIS to "Accept Client certificates" in IIS Manager (we do not have "Require SSL" check marked in the SSL settings of our website). Occasionally when we attempt to get the client certificate in with the following code (Asp.Net):
httpAuthenticationContext.Request.GetClientCertificate();
we get null. This issue is intermittent. Sometimes, GetClientCertificate() returns the expected cert.
While not this exact issue, we periodically have issues in our Azure implementation of requesting data from a file, database, etc. that we know exists, but fails to return data.
We learned to just wrap these calls with some retry logic, with a brief delay in between. If the calls fail a few times in a row, we throw an error, but for these "transient" issues, sometimes a simple retry will do the trick...
Hope this helps

When service through external host name returns wsdl html instead of the expected response envelope

I have an IIS-hosted, WCF web service deployed on a UAT web server. In IIS, I have site bindings on this same web service--one for internal access (Ex: uat-nodotsinternalonly) and one for external access (Ex: mysvc.uat.mydomain.com).
When I use SoapUI to test against the internal host name (http://uat-nodotsinternalonly/MyService.svc), it calls the service and returns the response envelope as expected.
When I use SoapUI to test against the external host name (https://mysvc.uat.mydomain.com/MyService.svc), it calls the service and returns the WSDL HTML as would be seen in the web browser instead of the response envelope as expected.
We need to expose past our firewall for testing with a vendor. Our external client can browse to our web service using the external host name and receive the WSDL back in their web browser, but when they call it, it fails with a 302 error.
I’m far from an expert on security, but I believe our firewall is handling the security then forwarding over http to the UAT server. The redirect and variations seem as though there’s something to change in how DNS is managed or settings in IIS. Does anyone have suggestions as to how to narrow it down so that the call to the external service will work?
We too had a WCF service that in SoapUI was returning the WSDL HTML instead of the expected response when invoking a method. This was an SSL-enabled service, and the solution in our case was to edit the endpoint URL after creating the request so that it used https instead of http. This is because we found that for some reason it defaults to http even when you initially specify https when creating the request. Here's how to edit the endpoint URL in SoapUI:
In the request window, click the drop-down arrow on the URL.
Select [edit current..]
Change http to https, and then try your request again.
The problem with the client getting a 302 error was because the client was not sending a SOAP request envelope to our web service. The client was just sending XML.

is there any server configaurations needs to change for session management

I have developed an application with JSP and Flex. In that Flex application interact JSP with HTTP service. I deployed application in one server that server URL is with HTTP it is working fine. But when I deployed this project in another server (HTTPS) the application is not running. There in JSP session is not handled. Is there any server configuration whicn needs to be checked?
I have no idea what you're talking about with "session is not handled". Please elaborate the problem in developer perspective, not in enduser perspective. What exactly happens? What exactly happens not?
I can at least tell that sessions are usually backed by cookies. Cookies on its turn are usually bound to a specific domain and path. Cookies are not dependent from the protocol used. Roughly said, if the webcontainer has created a cookie to track the HttpSession, it will by default use the request.getServerName() as cookie domain and request.getContextPath() as cookie path.
So if you for example have this webapplication on http://example.com/context, then the cookie will be created for host example.com and path /context. Regardless of the protocol. But when you fire a request on http://example.com/anothercontext, then by default you won't get the same cookie back and thus also not the same session.
However, most webcontainers provides configuration options which can influence the cookie host and path. Tomcat, for example, supports an emptySessionPath attribute in the HTTP connector which causes that the cookie path is always /. This way the http://example.com/context and http://example.com/anothercontext will be able to share the same cookies and thus also the session.
This knowledge of how it all works "under the hood" must give a better understanding of your problem and thus also ease nailing down of the root cause.

Resources