How to handle facebook login with a subdomain? - javascript

My application client side serve using aws cloudfront/s3. www.example.com
My server side is nodejs in ec2. api.example.com
I want to do login with facebook.
I set facebook to redirect after login to api.example.com/api/facebook/return.
Now when I on api.example.com/api/facebook/return I need to get back to my application www.example.com with the user loggedin.
How to do it?
I don't want to use lambda (lets say this is not the solution for me).
I can't access to the localStorage to store the token and the user - cause safari doesn't support Hub in access to another localStronge domain.
Can't use cookie because I have LoadBalancer and stateless servers.
I try to send a 10 seconds token to the client and return back to the server (confirm the token) and then back to the client (access token).
but sometimes the computer is slow and I get expired.
I was thinking about one time token, but how to implement such a thing? or any other idea how to handle this?

Related

JWT Authentication on page load

I'm using JWT authentication in my node site with passport and am not sure I am understanding the concepts.
Say I'm an authenticated user with my token saved in local storage. Say I then navigate to a /user page, which will display data about my user. Normally, I would check if the user is logged in, and if they are not, they would get redirected to a login page. But in this case, since I can't send the authentication token from a page request, I have to load my /user page, then the page makes a request for user data, and if the data is not found, I redirect them to the login page via javascript.
Am I correct in how I would handle this? It seems like a bad user experience, having to wait and redirect twice. Is there a way around this? Is JWT just not what I'm looking for my implementation?
If you want to render the page server side, you should set the JWT as a cookie instead of using local storage. You would be able to catch, verify and use it when a user request a page.
But I have to say that modern web applications use client side rendering. So there's no need to store the JWT as a cookie. When requesting a page, you will recieve only the static assets and you will get data by queryng an API that could response with 401 (Invalid or Expired Or Missing Token).
It seems you were using server side rendering before. Now you want to use JWT and you have read somewhere that a common practice is to store it in LocalStorage (that's true). Now you are dealing with a server side rendered application architecture while tryng to mix client side rndered applications concepts.
You are not doing huge errors, but you should consider to fully render your application server or client( I suggest ) side. For the second option, google "Build single page application"

OAuth2 flow in web frontend and REST API

I'm working on a project based on Phalcon which consists in two different stand-alone subprojects: a php + angular frontend and a php REST API.
I protected the API with OAuth2, using PhpLeague OAuth2 Server. The API server is the OAuth2's authorization server AND resource server.
This is the actual flow:
The user can browse the public endpoints of the frontend, and when hits a private page, gets redirected to the login page;
The login page has username and password, POSTs them to the frontend server;
The frontend server calls a public method on the API server, which is expecting a Password Credential Grant: it validates the credentials and sends back an access token and a refresh token;
The frontend server caches both the access and refresh token in session and uses it for some API calls: the first of those is the '/users/me', which gets info about the current user and its ACL on the frontend sections;
The frontend server sends the page to the browser, which loads its javascript files.
Now, OAuth2 states that access tokens should be short-lived and refresh-token should be long-lived: in the frontend server logic, the API calls which receives a 401 (caused by the expired access token) are retried by sending first the refresh token to obtain a new access token via a Refresh Token Grant. If this second call is rejected, I assume the user is no more logged in (refresh token expired / revoked).
The pages are using Angular to perform data and ux/ui management. My question is:
should the Angular code call directly the API server?
Actually the first thing my javascript code does is to get a config object from the frontend server, which contains the access token too, and uses it to make the calls to the API server. The problem with this is that i should rewrite again the "refresh token logic" in javascript (after it expires, i get 401s), and by what I have read on the subject i understood that it is better to not make the refresh token visible to the client (as it can generate new access tokens).
So i was thinking about a "two step approach", where every javascript API call goes to an endpoint on the frontend server which relays it to the API server, but this is obviously slower (JS -> FRONTEND -> API and API -> FRONTEND -> JS).
What is the correct approach? It's not very clear to me if the frontend should be considered as two clients (php + js) which should work separately or not, as I imagine that an hypothetical iOS app would be making calls 100% against the API server.
I have used the same approach in my own projects. The problem that we have is that the client is not secure. In order to generate / refresh a token, you need to pass secure information to the authorization server.
I have done the same as you basically, let the back-end handle the tokens and their temporary storage. You cannot and should not trust the client with important information which lets you generate tokens. In terms of delays, I wouldn't worry about it too much since you're not going to be doing that much extra work, you won't even notice the delays. I have a system like this built and used by hundreds of thousands of users with absolutely no issues.
Now, you have said a few things in here which make me wonder what you are doing.
OAuth2 is not a user authentication system, it's an application authentication system. You don't pass a user and their password and generate a token for them, you pass a ClientID and ClientSecret and they generate a token for you. Then you have an endpoint which gives you the user details for this user, you pass your userid or username and get the details of that user.
A token expired does not mean your user is logged out. Those are two completely different things. How are you going to expire a token for example, when your user wants to log out? You can't, your token will still be valid until it expires after the set amount of time has passed.
A token can be used for let's say half an hour, but your user may use the website for 1 hour. So before you hit any API endpoint, you could check ... has this token expired yet? if yes then you can go and refresh it and keep working without having to bother your user with a new login screen.
The whole point of an OAuth2 system is to make sure that only authorised clients can access it. A client is not a user, it's an application. You can have a website for example and you only want users of that website to access your API.
You can have endpoints like ValidateUser for example, where you take a username and a password and return a yes or no and then you log your user in based on that.
Irrespective of language/framework, second approach is secure and better than first one because to get access token by providing refresh token to Authorization server, it still requires Client ID and Secret which should never be passed to Browser for security reasons.
In first approach, to make a direct call it will not work if your Authz Server is hosted on different domain than your frontend server because of Same Origin policy of browsers. Even if they are on same domain, still you are exposing Client ID and Secret which will compromise your frontend server

Same Domain SAML Request

I have some web application in my server which use ADFS for authentication let's say this is their URLs :
http://myServer/ManyWebApps/WebApp1
http://myServer/ManyWebApps/WebApp2
http://myServer/ManyWebApps/WebApp3
When the user access any URL under "ManyWebApps" hierarchy he can freely use the server function they provide through javascript and through the browser without further authentication:
http://myServer/ManyWebApps/Server/Function
Now, I need to detach one of my web apps to a new URL like so :
http://myServer/WebApp1
Will the user still be able to free access server functions under the "ManyWebApps" hierarchy :
access http://myServer/ManyWebApps/Server/Function from http://myServer/WebApp1
Note : both web applications are still on the same server and work with the same ADFS server, when the user enters http://myServer/WebApp1 he is authenticated, but will he be able to access functions on diffirent web apps on the server without further authentication?
P.S : I need to access a function without further authentication because making an AJAX request to the function while unauthenticated will cause the AJAX request to be redirected to the ADFS which it can't handle
CONFIRMED : The authentication is saved in http://myServer so no further authentication need to take place if both apps are on the same domain
When sending a request to the server, all of the user's cookies are sent including the authentication token. If the user's doesn't have the token in his cookies, the server will direct him to the ADFS. But since both web applications are under the same server, they share the same cookies which means once the user entered any address in MyServer hierarchy, he can free enter any in that hierarchy without further authentication

Is it possible to securely use OAuth2 on client applications without having to re-enter user credentials frequently?

I'm trying to authenticate multiple client applications with a backend REST API using OAuth2. I have three completely separate entities: backend API server, front-end Javascript app, and distributed mobile app. The clients are first-party applications, so they will take direct username/password input to generate access tokens.
So my question is: is it possible to authenticate to the backend REST API from these clients using OAuth2, without having re-enter user credentials every hour when the access token expires? I can't think of a solution that gives the access token a one-hour expiration, but yet seamlessly refresh the access token in the background without additional user input.
Yes, I know about setting an encrypted HTTP-only cookie containing the refresh token. That works fine for the Javascript app, but does nothing for the mobile app. Or any other non-web client that may pop up.
I thought that I had come up with a great idea, which was to use an additional authentication server to negotiate the authentication on behalf of the client. So, the client would send the authentication server the username/password, and the authentication server would then call the API, save the access/refresh token, and finally give the access token to the client application. The idea being that when the access token expires, the client could then send the access token to the authentication server, which looks up the refresh token, calls the API to get a new access token, and returns the new access token. The client has now refreshed its access token without ever knowing the refresh token.
But then I realized that I am essentially nullifying the existence of a refresh token, and instead trading an expired access token for a new access token. Unless I'm wrong, that is not really any better than just straight up giving the client the refresh token - if an attacker obtained an access token, he could forever have more access tokens.
Based on my research, I am coming to the conclusion that what I want to achieve is simply not possible. In that case, is the only possible method of having a persistent login to increase the access token's expiration time? That is a very poor outcome, in my opinion. Surely some other solution exists, right?!

Secure way to communicate OAuth token to javascript client

I am designing a multi-platform application at the moment (clients would include internally developed mobile apps, and an AJAX heavy javascript client initially) centred around a REST API. Since in the future the API may be open to third parties, I am looking at using OAuth 2.0 for authentication and authorization with the API.
I am trying to get my head around some of the security issues with this arrangement, particularly with regard to the javascript client. I don't want this client to behave like a third party client might, with a whole bunch of redirects and popups and stuff, which is what most OAuth documentation seems to focus on. Since it will be delivered from my own domain, I am thinking that the server side of the webapp can be the actual client, and store the client secrets and refresh tokens, while the javascript retrieves new auth tokens from the server as it needs them.
To put it in step by step form:
The user logs in using non-ajax html form, generating auth and refresh tokens which are stored server side. This sets a HTTP-only login session cookie.
The javascript client code is sent to the user's browser after login.
The javascript client makes a request to a resource that is part of its own application (not part of REST api) to retrieve the token. The session cookie ensures that the client is genuine, and the referer will also be checked. Auth token is returned.
The javascript client validates the token with the REST API.
The client can now use the token to make requests against the REST API until it expires.
If the auth token expires or the page is closed and re-opened, the javascript client can request a new token. The server side of the webapp takes care of refreshing the token and sends the new token, as long as the login session cookie is still valid.
Does this make sense, or would it leave massive holes in the system? In particular, is it insane to have a resource on the web that hands out authentication tokens based on a cookie being set?
Just make sure that any communication to browser is HTTPS, so that no one in the middle can steal your tokens. And set the "secure" flag on your auth cookies.
Most browser authorization schemes nowadays boil down to a session token that's passed in a cookie. The OAuth 2 scheme is a couple steps ahead because a) the tokens (can be) dumb tokens with no dangerous user info inside, and b) they expire.
(Just to put that comment in context: one time I popped open a session token from a site and discovered my home address and phone number was in there. Ack!)
I've seen code that does HMAC signing of requests inside the brower javascript, but it came with a huge disclaimer: don't use this in production. A signing scheme requires the client (javascript) to know a "secret" string, but the browser/javascript is so insecure that it amounts to handing your secret strings to the world.
But if you keep all your commuinication over HTTPS, then you're really just putting an OAuth twist on the familiar scheme of passing session tokens as cookies.

Categories