Facebook login without Valid OAuth redirect URIs - facebook

This is not about wildcard domains. It's about the need to add completely different domains to Valid OAuth redirect URIs on Facebook Login.
We have a web app where our clientes can setup their own custom domain (example.com, xyz.net, etc). We don't know what domains will be used.
On Facebook we have a single app that takes care of the Facebook login. It seems that we need to whitelist specifically every domain that uses the FB Login.
Adding the domains manually is not an option. What options do we have?
Thanks.

The simplest solution that I can think of is to use an intermediate identity service with a very lax redirect uri validation. There is a good discussion of this approach and some of the security concerns with it in relation to IdentityServer4.
I have used custom redirect uri validation for an identity service before but only for very restrictive cases as this is one of most exploited vulnerabilities in an OAuth flow. The flexibility that you would need would weaken security considerably.
To implement it in IdentityServer4 you would set up Facebook authentication on the identity server and register the identity server's address with Facebook. You would then create clients to represent your new domains. This could be a single client for everything (making things more insecure still) or you could add a way for your clients to register themselves with the identity server (for instance dynamic client registration).
When a client wants to connect to Facebook they will use Open Id Connect to connect to the identity server which will then communicate with Facebook. In IdentityServer4 the client would add middleware for this with UseOpenIdConnectAuthentication (see here for an example).
Long story should you can resolve your issue by using an intermediate identity service. The identity service will be the only url that needs to be registered to Facebook and your clients will register with your identity service which you will have control over.
With great power comes great responsibility though. Taking the path of least effort will lead to a solution that lowers security considerably. Enforcing a secure dynamic registration with the identity service such as dynamic client registration protocol will allow you to use a single strict redirect uri per client and make your system about as secure as you can reasonably get it.

Related

How to perform user registration and authentication between a single page application and a REST API with OpenID Connect

Consider that we have:
An SPA or a statically generated JAMStack website.
A REST API.
The website is being served with nignx that also reverse proxies to our API.
--
It is required that a user should be able to register/authenticate with an identity provider (say, Google) through the OpenID Connect protocol. For the sake of simplicity, let us assume that the user has already registered with our API.
Talking about authentication using OIDC, from what I have read on the subject, the steps you take are the following:
Register the application with the IdP and receive a client id and a secret.
When the user initiates a login (with Google) request on the API ('/api/loginWithGoogle') the API sets a state variable on the request session (to prevent CSRF) and redirects the user-agent to the IdP's login page.
At this page, the user enters their credentials and if they are correct, the IdP redirects the user to the callback URL on the API callback (/api/callback).
The request received on the callback has the state parameter (which we should verify with the one we set on the session previously) and a code parameter. We exchange the code for the identity token with the authorization server/IdP (we also receive access/refresh tokens from the auth server, which we discard for now because we do not want to access any APIs on the behalf of the user).
The identity token is parsed to verify user identity against our database (maybe an email).
Assume that the identity is verified.
-- The next part is what's giving me trouble --
The documentation that I have read advises that from here we redirect the user to a URL (e.g. the profile page)and start a login session between the user agent and the API. This is fine for this specific architecture (with both the SPA/static-site being hosted on the same domain).
But how does it scale?
Say I want to move from a session based flow to a JWT based flow (for authenticating to my API).
What if a mobile application comes into the picture? How can it leverage a similar SSO functionality from my API?
NOTE: I have read a little on the PKCE mechanism for SPAs (I assume it works for JAMStack as well) and native mobile apps, but from what I gather, it is an authorization mechanism that assumes that there is no back-end in place. I can not reconcile PKCE in an authentication context when an API is involved.
Usually this is done via the following components. By separating these concerns you can ensure that flows work well for all of your apps and APIs.
BACKEND FOR FRONTEND
This is a utility API to keep tokens for the SPA out of the browser and to supply the client secret to the token service.
WEB HOST
This serves unsecured static content for the SPA. It is possible to use the BFF to do this, though a separated component allows you to serve content via a content delivery network, which some companies prefer.
TOKEN SERVICE
This does the issuing of tokens for your apps and APIs. You could use Google initially, though a more complete solution is to use your own Authorization Server (AS). This is because you will not be able to control the contents of Google access tokens when authorizating in your own APIs.
SPA CLIENT
This interacts with the Backend for Frontend during OAuth and API calls. Cookies are sent from the browser and the backend forwards tokens to APIs.
MOBILE CLIENT
This interacts with the token service and uses tokens to call APIs directly, without using a Backend for Frontend.
BUSINESS APIs
These only ever receive JWT access tokens and do not deal with any cookie concerns. APIs can be hosted in any domain.
SCALING
In order for cookies to work properly, a separate instance of the Backend for Frontend must be deployed for each SPA, where each instance runs on the same parent domain as the SPA's web origin.
UPDATE - AS REQUESTED
The backend for frontend can be either a traditional web backend or an API. In the latter case CORS is used.
See this code example for an API driven approach. Any Authorization Server can be used as the token service. Following the tutorial may help you to see how the components fit together. SPA security is a difficult topic though.

Securing a public REST API used by one app

I need to build a REST API that will be used by one private SPA web application. The problem is that the REST API must be on a different server than the SPA, so it must allow CORS. For two layers of security, the API can require Basic Authentication over SSL plus check for the correct client IP address.
It will not be possible to have a user login process for the API, since it is a service used by the SPA. The user is already logged into the client that hosts the SPA. I will not have access to anything other than the user's ID, and the REST API will have no way to validate this user ID.
Because the user is logged into the client's server, the API can be restricted to requests from the SPA's IP address, but that still potentially could allow anyone on that server to use the API other than the SPA.
Is this adequate protection?
I am considering adding a third layer of protection in the way of an access token, but this would be also fairly simple to uncover. If you know the basic authentication information (easily obtainable) and your IP address matches the expected client IP, then you are able to call the API to get an access token.
Also, with an access token comes the complexity of dealing with expired tokens.
Is it impossible to completely secure an API that requires a web-based client?
How many layers of security are enough?

Secure RESTful web service using Symfony2

We are in the process of planning an iOS application in which users will need to be authenticated and authorized before they can interact with data provided by a Symfony2 web service.
Authorization will be implemented with ACLs, it's the authentication I'm not sure about.
From what I found in my research, there are a few ways to achieve the authentication part, but since there won't be any third parties accessing the data it sounds like basic HTTP authentication paired with a SSL certificate is the way to go. Is this correct?
Additionally, is a simple username and password secure enough, or is it better to add some sort of API key for identification?
If a key is needed and considering our users will be part of a group, should a key be bound to every user individually or to the group as a whole?
Finally, and slightly off topic, Symfony2 has FOSRestBundle, is there a defacto REST library for iOS?
For securing REST applications in symfony the FOSOAuthServerBundle is very useful. With it you can implement easy OAuth authentication for your app. OAuth is de facto standard for securing REST web services.
As https/ssl is pretty secure you can go for basic http authentication and/or the api key solution.
Wether to use a key and/or username/password is your personal choice.
If somehow requests can be catched in cleartext either one is compromised.
Keys in addition to username/password auth can have the advantage of seperating i.e. user contingents.
Basic http authentication is mostly used, therefore the chance of your client having already available methods to integrate it from his side are high.
You should always give out unique keys or username/passwords to every user in order to be able to log who did exactly what.
I'm not that much into iOS, sorry.

Rest application and authorization

I would like to build my own REST app.
I'm planning to use oAuth as a main auth approach.
The question is: Can I use login and password as client_id and client_secret (in terms oAuth spec) ?
I don't have any third side applications, companies, sites etc... which will authenteficate my users.
I have my own REST server and JS-application.
Whole site will be made in usual(RPC) approach, but some private part will be done as RESTfull service, with enough stand-alone JS application.
UPDATED: I'm not sure that I even need full oAuth support. It seems to me that I can ask login and password on https page and then generate some token. Later i could use it to check is this user authenticated already or not. But in this case this oAuth become almost the same what we have in web aplications. I do not need oAuth to athorize users ?
I'm not consider HTTP(s) authotization because i don't want to send evrytime user and password to server.
No.
One if the main reasons OAuth exists is to allow integrations without users compromising their usernames and passwords.
If you plan on using username and password, look into xAuth as an option if you still want to sign your requests. More info: https://dev.twitter.com/docs/oauth/xauth.
But you could likely just as well go for HTTP Basic Authentication. At least if you publish your API over SSL. More info: http://en.wikipedia.org/w/index.php?title=Basic_access_authentication
I think you might get a better answer on the security site. See, for example, this question.
In any case, you need to start with a detailed assessment of what attacks you are trying to prevent and what attacks are "acceptable.". For example, if you are using HTTPS then you can probably accept the remaining danger of a man-in-the-middle attack, because it would require forging an SSL certificate. It is harder to say in general if a replay attack is acceptable.
One reasonable solution would be to create a time-limited temporary token by having the user authenticate over HTTPS with the username and password, generating a secure token with an expiration date, and then sending that token and expiration date back to the client. For example, you can create a (reasonably) secure token by taking the SHA1 hash of a secret plus the user name plus the expiration timestamp. Then the client can include the token, the user name, and the authentication timestamp in future requests and you can validate it using your secret and your clock. These need not be sent as 3 parameters; they can be concatenated into one string user|timestamp|token.
Register your application with SLI. SLI grants a unique client ID and a client secret that enables your application to authenticate to the SLI API. You must also register the redirect URI of your application for use in authentication and authorization flows.
Enable your application with specific education organizations so that the application can be approved for use in those districts.
Configure and implement the appropriate OAuth 2.0 authentication and authorization flow in your application, which includes managing sessions and authorization timeouts.

OAuth2 security considerations for client_id

When using User-agent flow with OAuth2 for mobile platform, there is no way for Authorization server to authenticate the client_id of the application.
So, anyone can impersonate my app by copying the client_id (and so get all access tokens on my behalf), and this is applicable to Facebook, Foursquare,...
This is not managed by OAuth2 ? Or I missed something ?
For Web applications (Web server flow), access token is stored on the server side, and the client is authenticated using secret key.
There's no good answer. Native app callbacks typically happen via custom registered URI schemes (e.g.: callback redirection URI is something like: myapp://oauth?code=xyz123). Unfortunately, any app can claim ownership of a given protocol scheme and receive the callback.
This problem is very synonymous with trying to lock down any protocol with "trusted clients". Think of the IM networks battle to lock out 3rd party clients (in early 2000's). Eventually they gave up - since whatever client & protocol endpoints are deployed could be reverse engineered by 3rd party developers.
Note: There is also some active discussion on this topic on the OAuth WG mailing list: http://www.ietf.org/mail-archive/web/oauth/current/msg08177.html
Normally client_id is associated with site's URL - OAuth responses/redirects will be sent only to the registrated Url. So attacker will not be able to receive results of the request on own site (unless somehow your and attacker pages are on the same domain).