I have two websites, both in separate domains. So for e.g. http://example1.com and http://example2.com. Both sites are in ASP .NET and use Forms authentication. Users of example1.com need to access certain resources of example2.com without needing to have accounts in example2.com. So whenever a user of example1.com needs to access a resource in example2.com, a temporary URL is generated through which the user can access the resource. The URL is a limited period one time use URL that is invalidated after first time use. Here is how it works.
When example1.com needs to access resource on example2.com side, a response.redirect occurs with an encrypted token in the query string. e.g. http://example2.com/path/resource1/?token=encryptedToken
This token is read on example2.com side and if it is valid, forms authentication is set to "temp user". "Temp User" is a limited access user created specifically as a proxy for example.com users.
Below is the code to achieve this in Application_AuthenticateRequest event
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
const string TempUser = "TempUser";
if (!Request.IsAuthenticated)
{
var url = Request.Url;
var token = Request.QueryString["token"];
if(IsKnownUrl(url) && IsValidToken(token))
{
FormsAuthentication.SetAuthCookie(TempUser, false);
Response.Redirect(Request.RawUrl);
}
}
}
private bool IsKnownUrl(string url){
//Logic to check the url is from known sources
}
private bool IsValidToken(string token){
//Logic to token is valid and not expired
}
This was working fine until both sites were switched to SSL. i.e. https://example1.com and https://example2.com. and this stopped working. The Response.Redirect from example1.com to example2.com goes into a 302 loop, which means for some reason the authentication cookie is not being set or accepted. When I view the network activity in Chrome Browser Developer tools, I see following trail
Name Status
https://example2.com/path/resource1/?token=encryptedToken 302
https://example2.com/path/resource1/?token=encryptedToken 302
https://example2.com/path/resource1/?token=encryptedToken 302
..................
Finally the Browser gives up and indicates the page is redirecting too many times.
Any ideas on what could be wrong?
Thanks Aydin for your tip. For anyone who is also facing similar issue, here is the solution.
After checking with Fiddler, I found that Authentication cookies (.ASPXAUTH) were being sent from the server but the browser was not sending them on subsequent requests.
Also, the URLs from example2.com were being displayed in example1.com inside an IFrame. After some searching I found that for IFrames, the browser will send cookies only if "SameSite=None" is specified in the Set-Cookie response header.
So in the end I had to update my code to create the ASPXAUTH cookie manually since the cookie created by FormsAuthentication class sets its to "Lax".
Related
I am working on Selenium testing for a project that is accessed via JSP which uses SAML to authenticate the user. I cannot find a way to provide credentials through to the SAML page, which is accessed through a 302 redirect.
I want to log in to home.domain.com/run.jsp. When I visit the page, I get a 302 redirect to auth.domain.com/adfs/ls/wia?SAMLRequest=<long_token>, where I fill in the browser's dialog window with my credentials. After submitting them, I am redirected back to home.domain.com/run.jsp, but with access this time.
The common Selenium auth answer seems to be adding the credentials to the url (admin:passw0rd#home.domain.com/run.jsp), but that doesn't pass the credentials through the redirect, and I even get a warning: You are about to log in to the site "home.domain.com" with the username "admin", but the website dos not require authentication. This may be an attempt to trick you.
My workaround for this ended up waiting for the redirect, then add the credentials to the current url and re-load the authentication page. If somebody has a better answer, I'd accept it because this is definitely hacky.
driver.Navigate().GoToUrl("home.domain.com/run.jsp");
Thread.Sleep(1000); // wait for redirects
// if the SAML didn't automatically authenticate and return us to the homepage
if (driver.Url.Contains("SAMLRequest")
{
driver.Navigate().GoToUrl(driver.Url.Replace("://", "://admin:passw0rd#"));
}
We have a straight forward ASP.NET web application with a login page. After the user enters credentials and submits the form, the server processes the details and if successful, Response.Redirect()'s the user to the Main Menu page. (We also have a navigation bar where the user can navigate to other pages via similar response.redirects)
One of our customers is setting up an IBM Data Power Web Application Firewall, and has told us this Redirect after a POST is an RFC violation and consequently the application does not work.
There are a few questions here that are related to Get/Post/Redirect, and they indicate that its up to the discretion of the browser to use the 302 response as a get or a post. I have also found other links on the public internet that lead me to believe this something the IBM device could be configured to handle.
Before I suggest changing the IBM device configuration, are there any configuration based (or simple code) ways to make a trivial login page (not using the asp.net login control) work where a GET request can send the login credentials, or make all postbacks in the site use a GET instead of POST?
Also, if anyone has tips for working with this IBM device, they would be appreciated.
An example of the code...
var userName = txtUserName.Text.Trim();
var password = txtPassword.Text.Trim();
var authResult = GetAuthService().AuthenticateUser(userName, password);
if (authResult == true)
{
//set forms auth cookie
Response.Redirect("Menu.aspx", false);
}
else
{
lblError.Text = "Unable to login";
}
A POST followed by a redirect is a usual mechanism found in many implementation. For example, consider using JAAS authentication. You present a form to a user and it is posted on '*/j_security_check' URL. Once authenticated you are redirected to a resource page, else you are re-directed to an error page.
I am not sure what is configured on datapower, but if your developer is using MPGW construct for this, then he can try playing around with two properties found in 'Advanced' tab of it. One is 'follow redirects' and another one is allow 'empty request'.
May be this helps you.
I am developing a console application in C# to do some background scraping from a web site. There is no use of webbrowser, winform or ASP etc., just plain http request & response.
I have this problem of logging out the site and the session is still alive so my relogging in is rejected soon after logging out because the site only allows one concurrent user to login. I have done google research and found no clue yet.
Here is the logout code:
public HttpResult logout()
{
HttpHelper http = new HttpHelper();
HttpItem item = new HttpItem()
{
URL = "https://w w w.mysite.com/logoff",
Method = "get",
ResultCookieType = ResultCookieType.CookieCollection,
Allowautoredirect = true,
};
HttpResult res = http.GetHtml(item);
return res;
}
I have used Httpwatch to have a peek of the request/response headers as well as the cookies. What I found is that the response contains three cookies with values zeros after logging out. My impression is that in the case of a browser, these cookies gets updated so relogging in request will be redirected to login page. How can I do it like a browser does it?
The problem I encountered was due to shutdown by TerminateProcess that forced a closedown of of my main app along with the logout before it had a chance to run.
So I replace TerminateProcess with a soft close which gives signal to the logout to run properly before my main app's close. I also cancel the logout step I used before login. This way, the cookies are invalidated and stored at logout. Now if I try to login right after logout, everything is fine because of the magic in the cookies. One lesson learned is that we need to use CookieCollection in stead of simple cookie when making request. The former will take care of updating cookies in the cookie container.
Using ASP.NET MVC, sessions are stored in SQL database (never had a problem with them, and didn't use web farm). Using also Twitterizer2 library. Using Firefox.
First request, no browser instances is opened. Browser instance is started.
We have simple form "Publish on twitter" and submit button Share.
When Share is clicked we store message in Session and redirect to Twitter's OAuth authentication (on POST submit).
We authenticate OK and return to our Action and before posting to Twitter we check if message is stored in Session (and it isn't! - it is lost immediately after Twitter redirection)
When we try another messsage Share it is now working (Session).
We solved it using a Cookie but we don't have a clue while we lost Session (first time) after returning from Twitter.
Any deas?
I'd like to ask how did you maintained the session without cookie the first time?
I think the problem can be of the cookie set process. I also experienced similar problem before a couple of weeks.
The problem was that when I make request for REQUEST token, this request is internal HTTP request (not via user browser). As a response to this request I get REQUEST token and then set it in the user session.
$token = getRequestToken();
$_SESSION['token'] = $token;
However, if the user just came to my site for first time without a session, he does not have a session cookie to sent me. Internally at the web site I have created a session for him, and stored the token inside it, but then instead of sending him response with cookie headers included, so that he "accepts" my session, I make redirect to the provider authorize endpoint. This way, the user does not get the session cookie, and when he is returned back, he is like a new user for my site.
This is the flow of the process that happened to me:
create user session in the database
setcookie(usersession) // add headers to the eventual response
get request token
set the token in the session
redirect the user (user does not receive the session cookie)
user goes to authorization point
user returns, but he is a new user for me
I'd be interested to know if you had similar problem :)
Best regards
check the request and callback domain are the same
i.e. you are making request for oauth from localhost and callback to 127.0.0.1
This has been a nagging issue for some time, but very sporadic and difficult to isolate.
From time to time, browsers that have authenticated on a web application, have been open for a while, have logged in and out of the same web application multiple times, have multiple tabs, are pretty much any browser (Chrome, IE, Firefox, Safari), and seemingly at random, lose their ability to retain an AuthCookie after being set and followed by a redirect. Closing the browser and starting a new session resolves the issue, as does opening up a different browser and attempting to authenticate.
Our team uses forms authentication for all of our websites and web application. This is a pretty typical setup where a login form is displayed, the user enters credentials and a cookie is set on the click event of the postback, then a redirect occurs to the same page where the cookie is then referenced and used to complete authentication.
In this situation
FormsAuthentication.FormsCookieName = ".WebAuth"
Within Event:
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, Username, DateTime.Now, DateTime.Now.AddMinutes(SessionTimeout), false, Username);
HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(authTicket));
Response.Cookies.Add(faCookie);
Response.Redirect(Request.RawUrl, true);
After the redirect, on PreInit:
HttpCookie authCookie = Request.Cookies[cookieName];
At this point, the authCookie variable is typically not null, but in these isolated circumstances that I've outlined above, the cookie comes back null after the redirect.
This happens very randomly, sometimes weeks before affecting one of our developers. As I said, restarting the browser resolves the issue.
Today I had it happen on our dev server while using Chrome. I had logged into the application, allowed the application to session timeout, and then attempted to login again. The attempted login then failed to set the cookie. I remotely attached Visual Studio to the process on the server to begin debugging. The entire time I could step through my code, even deploy new code versions to the server with updates, restart the app, restart IIS on the server, attach and reattach to the project, and the issue persisted in Chrome. In Firefox, I was able to authenticate without issue.
From Chrome, the login would validate, attempt to set a Response Cookie as outlined above. Prior to redirect, I could see the properly set Response Cookie, as well as its counterpart in the Request Cookies. However, on each redirect after a seemingly successful login, the Response and Request Cookie are gone.
I enabled Trace on the application to view the cookie collection:
There is a .WebAuth in the Request Cookies Collection, as well as ASP.NET_SessionId and several ASPSESSIONIDxxxxxxxx, but when the page loads, only the ASP.NET_SessionId and ASPSESSIONIDxxxxxxxx cookies are available in the Request.Cookies scope, no sign of the .WebAuth. However, in the page's Trace information after render, there multiple .WebAuth cookies listed, it is just that the page seems to have no access to them.
Primarily, on a working version after authentication there is both a .WebAuth Response and Request Cookie in the page's Trace info. But on a non functioning browser window, the Response Cookie is absent.
Has anyone else had any experience with this? It is such a nagging issue, and so sporadic, but I would love to be able to resolve it. My concern is that it may be affecting users and we would have no knowledge since the description of the issue is so convoluted.
Based on your scenario you may be running into browser's restrictions on number of cookies per domain/total. The limits are relatively high, but exist (spec: http://www.ietf.org/rfc/rfc2109.txt, section 6.3 , some recent information - http://www.nczonline.net/blog/2008/05/17/browser-cookie-restrictions/)
If you get it happening again try to look at actual server responses (i.e. using Fiddler) to see if cookies are send to the browser. Check what cookies are set for the domain and current page (depending on browser there are different ways of doing it, in all browsers you can see some cookies by running following in address bar javascript:alert(document.cookie) )
This is a non-persistent cookie issue. Session simply times out.
Try changing false to true in this line:
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, Username, DateTime.Now, DateTime.Now.AddMinutes(SessionTimeout), true, Username);
Also add
faCookie.Expires = DateTime.Now.AddMinutes(SessionTimeout);
I have fall in similar situation, things was certain as you described. But, later the reason have been found.
ASP.NET and IIS understood MyApplication and myapplication as one equal, but browsers undertood them as different. So, when we set auth cookies for /MyApplication, they were not sent to the server, when we go to /myapplication.
The fix is next:
protected void Application_BeginRequest(object sender, EventArgs e)
{
string url = HttpContext.Current.Request.Url.PathAndQuery;
string application = HttpContext.Current.Request.ApplicationPath;
if (!url.StartsWith(application))
{
HttpContext.Current.Response.Redirect(application + url.Substring(application.Length));
Response.End();
return;
}
}