How to configure a Facebook Application for sub domains - facebook

I'm building a Multi-Tenant application and I'm struggling incorporating a Facebook Login into the web application.
The tenants are using a sub-domain for example
http://tenant-1.domain.com/
http://tenant-2.domain.com/
http://tenant-3.domain.com/
So, I have created an application and when it comes to add the Website, how can I make it to be available in all tenants? Something like:
But of course, that does not work, and if I add just http://domain.com/ it does not work either on http://tenant-1.domain.com/ as soon I click in the <fb:button-login> I get:
How do I do this, without creating a specific FB App for each tenant?
I'm using this to help persons to subscribe their account, I just want the login to get name and email, or they need to fell that up in the name and email boxes...

This is not possible, but there are options to workaround. I think probably the best would be to use a single domain to perform the authentication, specified as the redirect_uri. On this redirect_uri you can append some query parameters, for example your redirect_uri could be:
http://auth.domain.com/auth.php?tenant=tenant-1
Then in the code for auth.php you would grab this tenant parameter from the query string, authenticate the user, store their access token and then immediately redirect them back to tenant-1.domain.com
I'm not sure if this solution will be something you prefer, but it is currently not possible to specify subdomains for authentication, so this or a similar workaround is necessary.

Related

How to map social credentials with custom ones

My company has userbase of course, but I want to allow users to login and use my applications with their social accounts e.g. Outlook, Facebook, Gmail. Something that is usually not clear to me when I read resources on the Internet on the topic is how to map the social credentials with ones in our database? I know we should use an API platform or something like that, but the user identity part is not clear to me.
You basically need to, as you noted, tap into the provided response and transform or link or provision it to existing identities in your own userbase. A lot of this depends on your method of delegating authentication to external provides and things they expose back to you as part of the user profile. You basically need to grab the user profile, parse it and then determine which field can be used to link that profile to an existing account, and then establish the authentication session based on the final result.
Here is a link to a technical walkthrough that describes the same process with an SSO solution: https://apereo.github.io/2018/04/20/cas-delegated-authn-account-linking/

Architecture for User-Registration (here: With using Facebook)

Im writing a user registration mechanism by hand so I dont want to use existing plugins or something.
Im wondering what the best way would be. I planning to do the following abstract steps:
Writing an component which is in charge to output a button which calls the facebook-api --> login in via facebook (Im getting token and user name/id)
In my route im using that Data to call the REST-Server-Backend of my app. I will pass the token as well as the username/id to the Server. (POST api.myapp.com/users)
The Server recieves the request and will validate via Facebook-API
the user data and token on its own --> if valid: Add new user to
database.
If the user wants to login now (after registration) he will do again
step no.1 and than will ask the server if the user is existing. But
how: Since ember suggest that the REST-Server is somekind of a
CRUD-Server and using the store is for working for model data only, there
is no possiblity to do a "logic"-call to the server like "ask
him if user with id is existing". Should I call "GET ../users/" and than check in my route if the sum of the returned records are smaller than 1?
So is that a common pattern?
Sounds like a fairly simple OAuth workflow but obviously refer to the facebook docs. As far as point 4 is concerned, I would suggest that yes, on login you make a request for the login route on your server (which should abstract the facebook OAuth call), and if the user is authenticated, then send down the user resource, otherwise redirect them to the login and send down some sort of 401 HTTP error.
As all your API calls should be authenticated too your user won't be able to access any protected API resources.
I would also suggest you look into an ember plugin like ember-simple-auth which also supports OAuth.
You can find more information about OAuth2 workflows here.

How to ensure of a referrer to a website?

Can anyone think of a neat solution for this; we operate an website service and sell to large organisations. Rather than have a logon for everyone, we'd like to be able to provide a direct link to our website from the organisation's Intranet page. We'd then like to check the referrer and if it's in our listed of 'trusted referrers', i.e. the intranet url, then we grant logon without asking for credentials.
I'm aware you can do $_SERVER['HTTP_REFERER']; to get the referrer, but I'm also aware that can be spoofed. Can anyone think of how we could achieve what we want, but while also guaranteeing it won't be hackable?
Thanks in advance
It's not exectly what you want, but to make logging on easier and ensure you don't need to store all the passwords you could use, for example, OpenID.
I think that there is no perfect and safe solution for this.
One solution would be to append tokens to the urls. It will work and it will be save, but anyone who knows the link (including token) will be able to login as that organization
Another solution would be to check the source ip. This can be done in different ways *apache, load balancer, app, etc).
Also a combination of token + ip could work (this token for that organization but only if the request comes from allowed_ips for that organization)
A more elegant solution (which I implemented for several big companies) would be to integrate you website login with the active record domain login. It is possible to use the current user window login as login into a website, using domain authorization. If a user is logged in into a domain, when enters your site will automatically login to the website.
This solution is much more easy to implement than it sounds. But, requires Active directory and workstation that connects to a domain to be in the company (this shouldn't be a problem, most of corporations are using windows on workstations and active directory for domain controller). Also is working best on IE only (direct login to the website). On other browsers the domain login popup will appear and user will have to enter again the domain password.
Also, I am pretty sure that can be made to work on linux environments, but I have no idea how.

Representation of a User in REST

I'm slowly beginning to unerstand REST and theres one thing thats confusing me .
I understand that most of the things in REST is a "resource" . So i was wondering what kind of a resource would we be referring to in the case of a user signup / login ?
Is it users ? Then does it mean that a POST on users would signup for a new user . If that is the case , then how do i authenticate a user ? a GET on users with an encoded password / username pair?
I'm really confused with this.
I may be COMPLETELY wrong in my understanding given that i'm just starting to understand REST.
Any help is appreciated !
Thanks!
It's a bit of an unusual but common problem for REST. Keep thinking about resources.
When you login you're asking the server to create a session for you to access certain resources. So in this case the resource to create would be a session. So perhaps the url would be /api/sessions and a POST to that url with a session object (which could just be an object consisting of a username or password and perhaps the UUID) would create a session. In true REST you'd probably point to a new session at /api/sessions/{UUID} but in reality (and for security purposes) you'd probably just register a session cookie.
That's my own personal approach to login forms if I were to implement them myself but I always tend to use Spring security for that job so this requirement never really takes much consideration.
I am working on something similar and this is the solution I have taken so far. Any suggestions welcome :)
I have users exclusively for singup and account modifications.
GET /users/{id} gets a user for the profile page for instance
PUT /users creates a new user with username and password. In reality this should send an email with a link to somewhere that confirms the signup with a GET method.
POST /users/{id} modifies the user (for example change password)
DELETE /users/{id}
For authentication I tend to think that the resource I request is the token or the authentication. I have tried to avoid the word "session" because it is supposed to be anti-RESTful, but if you are just creating the illusion of an actual server-side session for your clients, I guess it is fine.
PUT /authentication/ with usename/password returns Set-Cookie with the pair user_id / hashed value. Maybe it should be POST. Not sure
DELETE /authentication/{user_id} just deletes the cookie and the user is signed out. Maybe instead of user_id it should be a unique token_id.
Resources can be created, read, update and deleted using a restful approach, see e.g.:
https://cwiki.apache.org/S2PLUGINS/restful-crud-for-html-methods.html
So if you'd like to administrate you users this would be the restful approach to do so.
If you'd like to authenticate the users which you have in your administration dataset you need
to design or select a restful authentication mechanism see e.g.
http://de.slideshare.net/sullis/oauth-and-rest-web-services
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
For a jumpstart on these issues you might want to check out dropwizard:
http://dropwizard.codahale.com/
A resource may have one URI or many
but One URI will have exactly one Resource
Therefore, When Authenticating a user, you are addressing a user who is already registered
While when registering, you are addressing the user (resource) which is yet to be registered.
All you need is a way to process it to your SERVER.
THIS is an example taken from SUGARCRM REST web services implementation.
REST is like http requests to your SERVER.
For eg, when implementing REST Web Services.
Every REST Request is going to same File say
www.your_domain.com/Rest.php?json={your_json_method:'method',params:'watever'}
Where in Json is the request you are sending as a parameters
Requesting to authenticate a user
{method:'SignUp', username:'abc', pass:'pass', confirm_pass:'pass'}
Requesting to register a user
{method:'Login', username:'abc', pass:'pass'}
by this way you can have as many params as you want
Remember JSON is not necessory to be used. you can use simple get params for your query

How to use the same facebook application for different websites

I'm developing a small CMS in PHP and we're putting on social integration.
The content is changed by a single administrator who as right for publishing news, events and so on...
I'd to add this feature, when the admin publishes something it's already posted on facebook wall. I'm not very familiar with facebook php SDK, and i'm a little bit confused about it.
If (make it an example) 10 different sites are using my CMS, do I have to create 10 different facebook application? (let's assume the 10 websites are all in different domains and servers)
2nd, is there a way for authenticating with just PHP (something like sending username&password directly) so that the user does not need to be logged on facebook?
thanks
You might want to break up your question in to smaller understandable units. Its very difficult to understand what you are driving at.
My understanding of your problem could be minimal, but here goes...
1_ No you do not create 10 different facebook application. Create a single facebook application and make it a service entry point. So that all your cms sites could talk to this one site to interact with facebook. ( A REST service layer).
2_ Facebook api does not support username and password authentication. They only support oauth2.0. Although Oauth is not trivial, but since they have provided library for that, implementing authentication is pretty trivial.
Please read up on http://developers.facebook.com/docs/.
Its really easy and straight forward and well explained.
Your question is so vague and extensive that it cannot be answered well here.
If you experience any specific implementation problems, this is the right place.
However to answer atleast a part of your question:
The most powerful tool when working with facebook applications is the Graph API.
Its principle is very simple. You can do almonst any action on behalf of any user or application. You have to generate a token first that identifies the user and the proper permissions. Those tokens can be made "permanent" so you can do background tasks. Usually they are only active a very short time so you can perform actions while interacting with the user. The process of generating tokens involves the user so that he/she has to confirm the privileges you are asking for.
For websites that publish something automatically you would probably generate a permanent token one time that is active as long as you remove the app in your privacy settings.
Basically yuo can work with any application on any website. There is no limitation. However there are two ways of generating tokens. One involves on an additional request and one is done client side, which is bound to one domain oyu specifiedin your apps settings.
Addendum:
#ArtoAle
you are right about every app beeing assighend to exactly one domain. however once you obtained a valid token it doesnt matter from where or who you use it within the graph api.
let me expalin this a little bit:
it would make no sense since it is you doing the request. there is no such thing as "where the request is coming from". of course there is the "referer" header information, but it can be freely specified and is not used in any context of this.
the domain you enter in your apps settings only restricts where facebook redirects the user to.
why?
this ensures that some bad guy cannot set up a website on any domain and let the user authorize an app and get an access token with YOUR application.
so this setting ensures that the user and the access token are redirected back to YOUR site and not to another bad site.
but there is an alternative. if you use the control flow for desktop applications you don't get an access token right after the user has been redirected back. you get a temporary SESSION-TOKEN that you can EXCCHANGE for an access token. this exchange is done server side over the REST api and requires your application secret. So at this point it is ensured that it is YOU who gets the token.
This method can be done on any domain or in case of desktop applications on no domain at all.
This is a quote from the faceboo docs:
To convert sessions, send a POST
request to
https://graph.facebook.com/oauth/exchange_sessions
with a comma-separated list of
sessions you want to convert:
curl client_id=your_app_id \
-F client_secret=your_app_secret \
-F sessions=2.DbavCpzL6Yc_XGEI0Ip9GA__.3600.1271649600-12345,2.aBdC...
\
https://graph.facebook.com/oauth/exchange_sessions
The response from the request is a
JSON array of OAuth access tokens in
the same order as the sessions given:
[ {
"access_token": "...",
"expires": 1271649600, }, ... ]
However you don't need this method as its a bit more complex. For your use case i would suggest using a central point of authorization.
So you would specify your ONE domain as a redirect url. This domain is than SHARED between your websites. there you can obtain the fully valid access token and seamlessly redirect the user back to your specific project website and pass along the access token.
This way you can use the traditional easy authentication flow that is probably also more future proof.
The fact remains. Once the access token is generated you can perform any action from any domain, there is no difference as ther is literally no "domain" where the request is coming from (see above).
apart from that, if you want some nice javascript features to work - like the comments box or like button, you need to setup up open graph tags correctly.
if you have some implementation problems or as you said "domain errors" please describe them more clearly, include the steps you made and if possible an error message.