Suppose I have domain-a.com (A) and domain-b.com (B)
I'd like to be able to share php sessions between the two domains unifying logins in a way that once the user is logged to A is automatically logged into B and vice versa.
Now, the problem I'm facing is that even if I managed to have the browser talk via ajax to an external domain via the Access-Control-Allow-Origin header it won't set cookies (please don't tell me "you can't set/get cookies for another domain, this is not the problem")
here's the flow:
A sends credentials to B
if credentials are OK
-B answers with the SESSID made in order to be consistent with the user credentials (so that it can be generated both ways ie: login from A or login from B), this will be used later to share the session created on B
-At the same time I'd like that B could write cookies for its domain, but so far I wasn't able.
What I need here is very simple, once that the credentials from A are correct i'd like that server B could write his cookie for his domain (B), I can see from the headers that technically it's setting cookies, but the browser isn't really listening. any idea? am I playing in a dangerous zone of incompatibilities between browsers? technically all of this should be pretty vanilla for the recent browsers.
thanks!
If domain-a.com and domain-b.com are on the same server, you can implement your own sessions or try to use session_id to set session ID. If they are on different servers, you`ll need to use some sort of replication or create an API to authorize users on third-party domains.
Related
I have a few domains all on the same server, with the same IP and the same databases - that can be accessed by all 5 of the domains.
I have recently remade my login system, so that on my main domain, the cookie works for not only the main domain but the sub domains as well. What this means is that if a user logs into one area, they are signed in everywhere. Which is great! I write a cookie with their hash (taken from the DB) and check for that when loading each page, and they are automatically securely signed in.
This is lovely, but the problem then comes when switching domains, as cookies seem to be locked down to domains. So my other domain (lets call it domain2.com) cannot read the cookie from domain1.com.
Are there any clever ways around this? I could write something to the database, such as IP, but that wouldnt be very secure as the company i work for everyone is on the same IP and therefore it wouldnt be specific.
Or I thought about maybe including a hidden iframe on the page, which actually links to a page on the main server, and pulls the information that way somehow.
I am not sure, but I am sure it can be done. Any ideas?
Browsers, for good reasons, do not allow cookies to be read from any other domain.
What you can do is have domain2.com redirect to a page on domain1.com which checks if the user is logged in and if they are it redirects back to domain2.com with the user's id which can then log them in.
You should not depending on original PHP session functions Collections.
Here is what I have done :
After login success , Server side should return a "session ID" to the browser and store by JavaScript or some how, mean while the "session ID" should be store in database as a successful signal and you do a login time next to the session ID if you needed.
Now you can share the session ID in any IP server you want and make your client connect to(some trick like you redirect to the new domain and post the SID) then establish a PHP session.
I have a server say 'XYZ' and many clients of different domain, say A, B and C. authentication is done at server.
- when user comes first time to any of the site, we will ask him to create the account for the site. he will enter email and password. we will sent the data to server and stores thr. now he has account in 'XYZ' so that he can login to any of the site A, B and c.
Next:for example say, He come to site B, to login, he enters email and password. we will take this data to server to verify, if password matches with email, we send status 'Yes' back to client so the he login successfully and go to inner pages.
Because sending email and status 'yes' back to clink is not safe. we are using socket programming. so that outside people will not know what data we are sending and getting back.
because we are using socket, we are not able to create any session or cookies, because we are not opening server site in browser.
I want,like: when user successfully logs into site B. if simultaneously in next tab he goes for site C. he should not asked for to login(should not show login page). he automatically gets logged in(goes to inner pages).
The thing you're looking for is called single sign-on (abbreviated SSO) and it is a hard problem to solve correctly. There are lots and lots of SSO schemes, all of which suck horribly in their own special way.
A major obstacle in the way of your goal is how we normally keep track of logins on the web: cookies. In particular, one domain can only set cookies that belong to it. This means that if your three web sites are on three different domains, you can not have one site set a cookie for the others.
A common way around this is to actually place the authentication service on yet another domain name. Whenever you need to check that a user is logged in, you direct them to that authentication service. A popular unified sign-on mechanism, OpenID, uses this technique. OpenID is what StackOverflow uses.
(If you use the various StackExchange sites, you may have noticed that you can sometimes be automatically logged in to the others after loading a page. I'm still not sure how this works, and haven't investigated yet.)
From what you've described, you'd be well-served by central authentication. You may even find that implementing a system based on OpenID could even work well for your sites... though if you do that, I encourage you to hide the complexity of the whole URIs-as-identities thing, normal end-users are unlikely to understand the concept.
Can you set a cookie in your browser after the user logins in the XYZ site?
So now when the user visits the site A, B or C, you can check whether cookie is set against XYZ domain, and if yes, you can login the user. But note that you can only share cookies across sub domains (of XYZ), not different domains.
Is there any way to login users to other sites using PHP with cURL or something else?
I want to provide logins for my users to other sites, but i don't want to show them the password, so they cannot change it on the other sites.
Not unless you proxy the entire session through your server.
My guess is it depends on the site.
Websites have a variety of ways to authenticate a user. If the website uses a session identifier in the URL, you could login for them, then pass a header('Location: http://someothersite.com?PHPSESSID=_____'); to the user and assume it just picks up with that session.
If they use cookies or IP-based system, it won't work because
a) you can't pass another domain's cookie on to the end-user (this would be a X-site attack), and
b) the server's IP is different than the users.
You might be able to fake that you're a proxy and use X-FORWARDED-FOR in your request, but even still that's a stretch.
SAML is often used for signle sign on (SSO) - http://en.wikipedia.org/wiki/Security_Assertion_Markup_Language
I have a small problem.
How do I set a cookie for multiple domains?
I do understand the security problems, and I am sure it has been done before. The reason for this is SSO.
ie.
account.domain.com will need to set domain logged in for:
domain.com,
domain1.com,
domain2.com.
Is there any easy way, using PHP and cookies, or any alternatives?
There is absolutely no way for domain.com to set a cookie for domain1.com. What you are attempting to do can only be solved by getting the user's browser to submit requests to each domain which will then set its own cookie.
Then you need a way for each domain to verify the user's identity. There are two approaches to this:
Back channel - the sites contact each other directly to determine if a user is logged in.
Passing a token in the GET or POST - when the user's broweser is redirected to the other site a digitally signed parameter is passed containing the identity and session status.
It's really quite complicated. I suggest you don't roll your own. Take a look at SimpleSAMLPHP for a PHP implementation of what I'm describing.
What you're attempting can't be done. (It's a browser security issue, not a PHP one.)
Other than using some form of off-site authentication, the nearest you can achieve is making a cookie accessible across sub-domains, in which case you just use the optional 'domain' arg of PHP's set_cookie function.
This can be done via one domain acting like a master and others like a slave.
Say we've got a domain accounts.domain.com and it's our master.
Then we've got our slaves domain.com, something.com and another.com
When you'll log on on domain.com, it'll be actually site accounts.domain.com, then you'll get a cookie with unique ID for your browser and then you'll be redirected to domain.com's post-logon landing page (ie. domain.com/logon?check=true&unique-id=<browser unique id>&request-id=<unique request ID>). the landing page will contact the accounts.domain.com, querying it with the browser ID. If the transaction's okay, then you'll get logon cookie from domain.com.
Next, on every domain (domain.com, something.com and another.com) will be initial redirect to accounts.domain.com/roaming-check?return-url=<URL the redirect was initiated from>. Because we're returning home (we're logged already on accounts.domain.com), we'll be redirected again on our landing page (<domain name>.com/logon?check=true&unique-id=<browser unique id>&request-id=<unique request ID>) and from this point it's the same as the part with logging on. We're seamlessly roamed to another domain (without user knowing it as browsers doesn't usually show the redirected page until it passed the headers send(server)/receive(browser) section).
In case there's in fact no active logon, the site will save this "negative logon" to session and not try to check logon anymore (until we try to logon or load another domain).
I think this solution will suit your needs: "Simple Single Sign-On for PHP"
Here's the quick version of my question:
Is it possible to set a cookie somehow into a client's browser when the cookie is for use with a different server (in this case an Exchange mail server)? In this scenario the server trying to set the cookie is at "intranet.myschool.edu" and the exchange server is at "owa_server.myschool.edu".
Here's the full question:
I have a php script that uses cURL to make an HTTP POST to our Exchange server that has Forms Based Authentication enabled.
When I make a successful HTTP POST (which includes the user/pass in the posted url), the Exchange Server (or more specifically, the https://my.school.edu/exchweb/bin/auth/owaauth.dll file) outputs cookies.
Specifically, it outputs a "sessionid" and a "cadata" id.
With these cookie ids written to a text file on the server, cURL/PHP can reference it and then request data (via webdav and such) from the Exchange/OWA server.
That part works.
The problem I'd like to solve is now passing the cookie ids to a clients browser, so that they can use these cookie ids to auto-login to their own OWA account.
In essence I would like our users to log into our intranet with their Active Directory IDs, and see a snapshot of their recent emails. Then, if they need to, I'd give them a little link to switch over to the full OWA web application. When this switch happens, I don't want them to have to login to the OWA manually. Since they already submitted their Active Directory UserName and password at the front of the intranet, I'd like them to be auto-logged into the OWA.
I should note that using Windows Authentication to try to do single sign on is not possible since we have a mix of Mac OS, Windows, and Linux.
I had thought that I would be able to do a "setcookie" and assign the cookie ids that cURL got and put them into the clients browser.
Is this not possible? Is it not possible to "spoof" Exchange/OWA (or any other site) this way.
I have legitimate cookie ids that cURL captured. Is there no way to pass these to a client browser on a different computer?
In a worst case scenario, would using Javascript to just auto paste the username and password into the OWA login page be my only hope?
Does anyone have any other ideas on how to avoid my double login problem with Exchange/OWA?
Thanks for any help provided!
From RFC 2965 (NB HDN = "host domain name)
Host A's name domain-matches host B's
if
* their host name strings string-compare equal; or
* A is a HDN string and has the form NB, where N is a non-empty
name string, B has the form .B', and B' is a HDN string. (So,
x.y.com domain-matches .Y.com but not Y.com.)
Note that domain-match is not a
commutative operation: a.b.c.com
domain-matches .c.com, but not the
reverse.
So using .myschool.edu as the domain should work. NB the leading . is essential
You may be able to set a cookie with a domain part of '.myschool.edu'. In theory that's then sent to any other site hosted under a subdomain of 'myschool.edu'.
In practise however, your client software may decide that the cookie's scope is too wide, and refuse to send it back.
I think this would be a serious security loophole if it were possible...
In this scenario the server trying to set the cookie is at "intranet.myschool.edu" and the exchange server is at "owa_server.myschool.edu".
You should be able to do that.
I do this on my site (which I will change the names for the purpose of the example):
I have a web app at url
webapp.domain.com
And when users login, I set the cookie of the PunBB forum package which is at:
forum.domain.com
By setting/clearing the PunBB forum cookie, I can automatically login/logout my users on their forum account for convenience (this of course assumes that the registrations are syncrhonized, in my case I removed the forum registration and the main site registration creates the forum account for the user).
All you need to do is in subdomain#1 to set the cookie path to "/" (the default), and set the cookie domain to "domain.com". Then your app in subdomain#2 should see the cookie.
EDIT: I see barrowc has answered, I've seen the ".domain.com" pattern in some examples, my site uses "domain.com" for the cookie domain and it works too (maybe php set_cookie adds the leading dot if missing?)
Your browser gets to decide that... but usually no, you cannot. That is considered a type of XSS vulnerability.
you could use an iframe to set the cookie, ie. have an iframe on your web server that makes a request to a page on your exchange http server (https://my.school.edu/exchweb/) with your wanted cookie vars set as get or post variables. then use the vars to set the cookie for that domain, and redirect the user to the exchange server.
now, there could be logic on the backend of OWA that checks ip address, user agent, etc.... when registering the session that may invalidate this..... not sure
We've been fighting this one hard for months, the best we can come up with is allowing the web server to get the cookie for Exchange at EVERY LOGIN. problem is, that without cookie affinity, we don't have a way to make sure that the cookie obtained by the web server came from the same load balanced node that the client connects to.