I'm experimenting with moving an existing enterprise app to HTTP 2.0 at my customer's request. The app uses ASP.NET Forms Authentication, and when accessed over HTTPS with HTTP 2.0-aware browser and server (Windows Server Tech Preview), authentication appears to succeed during the login action, redirecting to the requested URL, but then the server responds to the next request with a redirect back to the login URL again. After adding some diagnostic logging to Application_BeginRequest, I found that the auth cookie is present in the request, but an attempt to decrypt the ticket with FormsAuthentication.Decrypt() throws an exception stating that there are non-base-64 characters in the cookie. I suspect this has something to do with HTTP 2.0 header compression, but I would have thought that this should have been handled transparently by IIS and that the headers should have been decompressed by the time my code executes. Has anyone else experienced this and know of a workaround? Happy to provide additional information if I left anything out.
Related
I'm developping a webapp linked to a CAS server with phpCAS. Up to now everything was going well, I was able to access my app after the CAS authentication. I'm now supposed to implement a logout feature : when someone logs out of the CAS server, it sends logout request to all apps opened for that session.
The problem is my app doesn't seem to receive that request. I contacted the adminstrator who told me that he can see the request leaving the server. He then asked me to confirm him that my server received that request.
And here is the problem : I have no idea how to see if the server received the logout request (a json file...apparently a POST Method is used to send the data to the address of my app...as you see, I have no idea what I'm talking about.). I've been searching for days now and I'm totally in the dark. I tried to use tcpdump. I see a TCP F Flag when I logout of the CAS server so it seemed first like a good thing. But I have no idea how to see if my server has received a logout request.
Hoping that someone can help me...
Thanking you in advance.
And here is the problem : I have no idea how to see if the server received the logout request
You need to design some kind of filter/interceptor that sits in front of your application and intercepts all requests. This filter should examine the request body to see if the request is indeed a logout request. If it is, parse and consume the request body and begin to logout and remove the application session accordingly.
...with a little bit of searching and effort, it looks like phpCAS can handle logout requests on its own:
https://github.com/apereo/phpCAS/blob/master/docs/examples/example_logout.php
apparently a POST Method is used to send the data to the address of my app
Not "apparently"; rather, exactly. According to the docs:
The CAS Server MAY support Single Logout (SLO). SLO means that the user gets logged out not only from the CAS Server, but also from all visited CAS client applications. If SLO is supported by the CAS Server, the CAS Server MUST send a HTTP POST request containing a logout XML document (see Appendix C) to all service URLs provided to CAS during this CAS session whenever a Ticket Granting Ticket is explicitly expired by the user (e.g. during logout). CAS Clients that do not support the SLO POST requests MUST ignore these requests. SLO requests MAY also be initiated by the CAS Server upon TGT idle timeout.
And then here is the actual payload.
Our web application has user/password authentication. It runs on a web server which is secured itself with HTTP Basic Auth. This is just a temporary solution / workaround. The web application's authentication will be sufficient in future, but at the moment the web server Basic Auth prevents accessing the web application at all.
The web application returns status code 401 when not authenticated on application level. The WWW-Authenticate header defines a different realm, so the browser won't get confused between web server and web application authentication: If we didn't define a different realm the browser would throw away the web server credentials as soon as the application's 401 arrives.
So far so good. However our application has its own authentication dialog. For XHR requests we want to handle the 401 status on our own and need to prevent the browser's internal basic auth window. There is a simple trick for this: Just adjust authentication header (WWW-Authenticate) to use a custom auth method:
WWW-Authenticate: CustomBasic realm="myapp"
Whereby the web server returns:
WWW-Authenticate: Basic realm="webserver"
This works with Firefox but not with Chrome. Chrome ignores the realm when using CustomBasic and discards the credentials (user / password) for realm "webserver" as if we didn't define the realm "myapp" at all.
Do you know why? Do you know a solution with following requirements:
Keep 401 status for both realms
Do not show browser's basic auth window on application level (especially for XHR requests)
Yes I know we can simply workaround this by using different HTTP status codes on application level and handle them respecitvely. But if possible I want to keep the correct status codes 401. This could also be a valid use case, e.g. if you have two web applications accessible with two different URL paths on the same host.
I've written my own login app to protect my api following the oauth-login-app example.
I've implemented the web server flow and everything works great.
My question is: how should I handle an authentication failure at step 3? How do I tell he client app that the authentication failed? The user could either press the cancel button, or refuse permission or just enter the wrong details.
When you initiate OAuth 2.0 (dance) with
/authorize
the user-agent land on /login page (created/hosted by you),
post redirect.
enduser(user-agent) submits the username/password
to the page hosted by you. Here you collect the credentials and
submit to Apigee, and if authentication fails, send a HTTP 401
response. Now your application should be in position to re-render
the login page and with a flash "invalid credential".
Now coming to if user is authenticated but rejects the authorization request in
consent page, you should redirect to the "redirect_uri" provided
by client, with error code.
How do I tell he client app that the authentication failed?
The login app will redirect the control back to the application redirect URI - with added error code/description in the URL as hash parameters. In case of success the URL is appended with code or token.
You can do this redirect from your login app directly but I would suggest to make the redirect call first to an Apigee Proxy and let Apigee Proxy send the redirect back to app. Both in case of success and failure. In this way you will have the benefit of using Apigee analytics that helps your understand how many OAuths failed for what reason etc.
EDIT:
You can use the same GenerateAuthorizationCode proxy you have built for the success flow. When login fails or succeeds, in either case you need to pass that information to this proxy. Generally the login app and this proxy should share this information using a common session store. You can not pass this information just using a redirect parameter because that can be changed by the client user agent. When you redirect to the GenerateAuthorizationCode redirect proxy, do so by appending a random session ID in the URL. That id can be used by the GenerateAuthorizationCode proxy to look up the login status from the session store. Then you can either send back a redirect with error or a proper oauth code based on if the login was successful. An easy implementation of the session store can be done using a distributed caching resource in the apigee gateway. Login app can put/get the session using an internal API. While the proxy can use policies to retrieve the session information.
I have two virtual directories, one hosts an application the other hosts a web service layer running WCF with ASP.NET compatibility mode enabled.
The service project has an HTTP module that deals with authentication for incoming requests. The login service writes an authentication cookie to the client.
Subsequent requests are handled via AJAX (jQuery) to the services from the application project (another virtual directory on the same domain.)
Cookie domain is set correctly, the cookie path is "/", the cookie is set to HTTP ONLY so that scripts cannot interact with it.
My issue is the login service seems to be sending the SET-COOKIE header with the correct payload in the cookie, however the subsequent requests are not sending the cookie back to the server, in fact when inspecting the local store the cookie is not even there.
Potentially what could be my issues?
We tracked the issue down to Chrome. Apparently there was a prior bug that seems to be presenting itself again whereby expires cookies are not promoted to session and are instead discarded.
We are deploying our ASP.NET 3.5 app to a production server for beta testing.
Each page is secured using SSL.
On our homepage (default.aspx) we have web services which populate flash objects.
I am getting an error:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'.
Also, when using firefox, receive the Windows Login pop up screen.
Does anyone have any clue what or why this is happening?
Much thanks!
I would think that the request from Flash to the secure web services doesn't have credentials or that the secure certificate in the response can't be validated.
Probably both.
So in flash there will probably need to be some code like:
request.Username = "xyz"
request.Password = "***"
or something similar
In .net there is a way to manually override the validation of a certificate for the request. I'm not sure how you would do that in Flash.
I'll update this if I find a sample for the .net way.
Sounds like IIS isn't configured for anonymous access.
If you believe you have it setup correctly (sounds like it isn't), then you might try troubleshooting your connection with Wfetch.