Login without redirect Auth0 on SPA - javascript

I'm implementing Auth0 in my SPA app, one of the requeriments is to have a custom UI, that also implies that i cannot use redirects to the Universal Login Page of Auth0.
After reading throught the Auth0 website, i found the Resource Owner grant type, which seems to solve my problem to handle a login directly using Auth0 API.
Is there any drawbacks of using this grant type?? (I read that is not very recommended, but i wanna hear opnions about this)
Also, is there any alternative to this grant type?? I mean, i'm stuck with this solution if Biz doesn't want redirections?? Thanks.

Resource Owner Password Grant
This can sometimes be a useful 'bridging solution', but it has some disadvantages as summarised in this article from a couple of years ago. These are perhaps the main downsides:
Single Sign On across apps won't work
Federated login options won't work (Integrated Windows / 2 Factor)
Security reviews may perform less well
Redirecting for Logins
It is very standard to redirect users to login, which signifies that you are externalising security to an expert provider. Most systems do this, including Gmail and Office 365:
You start at mail.google.com
For logins you are redirected to accounts.google.com
You then return to mail.google.com
My blog page shows the login redirect user experience for Web / Desktop / Mobile apps and there is an SPA there which you can run.
Of course, if your app is well coded there should be no down side to redirects. Eg the app should maintain the user location within your SPA, and also any data the user is editing.

Related

What protects my Facebook application from being impersonated?

Facebook JavaScript SDK guide contains an example code to integrate Facebook login and authorization for a specific application. The only information provided to this script is the App ID.
Let's say an user authorizes my application to access his private data. Now, what prevents someone else to put a Facebook login form on his own application using my App ID and JavaScript to make it look like it came from my domain and access this user's private data?
Do browsers provide enough security on this subject?
Now, what prevents someone else to put a Facebook login form on his own application using my App ID and JavaScript to make it look like it came from my domain and access this user's private data?
Do browsers provide enough security on this subject?
Nothing to do with the browser, really. Facebook will only pass data back to a domain that's in your whitelisted set of app domains in the developer console.
When the SDK redirects user to Facebook, Facebook's servers redirects back to your site. The redirect URL is set by you in the App Settings of Facebook Developer Center. If someone steals your App Id and puts it in his site, all of his users would be redirected to your site.

Are Javascript Instagram applications that authenticate with client_id allowed?

A few web-based applications I maintain have been using JavaScript on the page to fetch posts from Instagram* through their API, only authenticating with a client_id. With the Instagram API changes recently (applications are sandboxed until approved) this no longer works.
Is this kind of application allowed by Instagram? Or is it considered a security risk to expose the client_id in the Javascript that performs the request? If it matters, the application is for internal use by a few employees only.
* Specifically, the 10 last posts from a fixed user.
All instagram API endpoints now require a valid access_token rather than client_id. The search endpoint is an example of one that didn't previously require an access_token. You can find this in the Change logs
All API endpoints require a valid access_token
All API endpoints require a specific permission scope granted by the user
You can authorise your own account and grab the last 20 posts, but for any more than that you will need to submit your app for review
Try to create a new app.. My app was deleted instead of going to sandbox mode.
As you need 10 last posts, this should work on sandbox mode.
Content Display for Personal Website. If you are a developer and you want to showcase Instagram content on a website, then you do not need to submit your app for review. By using a client in sandbox mode, you will still be able to access the last 20 media of any sandbox user that grants you permission.

Firebase in Cordova/Phonegap: Log in using Email/Password from within app?

I'm running a webview from a cordova app and want to authenticate a user, I know they have the OAuth strategies but I need to use the email/password combination.
I'd like to keep things simple but may end up having to generate a token.
Open an InAppBrowser that loads an auth flow for firebase
Listen for that auth flow to be completed using this method: http://blogs.telerik.com/appbuilder/posts/13-12-23/cross-window-communication-with-cordova%27s-inappbrowser
Grab the result from the webview again and insert it into the webview firebase instance
I'm guessing that's not possible due to security.
My app is using Amazon login (required) so my alternative would be:
webview loads InAppBrowser with our external url
that loads Amazon auth, then generates a token for Firebase
webview listens for token and grabs it, stores it in localstorage
Edit:
In the firebase docs on logging in with a username/password, I see it returns a token for the session and more information in the authData object:
https://www.firebase.com/docs/web/guide/user-auth.html
Could I then take all the information from that object and send it back over to the cordova webview and then populate that Firebase ref with the information?
Some answers from the wonderfully helpful support at Firebase:
First:
You’re correct – anyone can make a request to sign up, and we don’t expose any capability to secure the url which people can sign up from for email / password authentication.
The main reason that we require / enable origin whitelisting for OAuth authentication, but not for email / password authentication, tends to revolve around sessioning.
The Firebase login server does not maintain sessions (via cookies or any other method), and so requests to the login server for password auth. requires a user credential (the password) for every request. CSRF is typically a risk when a malicious party can take advantage of a user’s session browser, i.e. make requests on behalf of the user to some page where cookies are automatically sent by the browser.
Furthermore, we don’t have a great way to actually do ideal origin-based whitelisting for these pure HTTP requests. We could use CORS, but would have to fall back to JSONP for older browser environments that don’t support it. To complicate matters further, PhoneGap / Cordova apps don’t have the same notion of an “origin” at all, and from the perspective of a server – the calls are indistinguishable from any malicious party making an HTTP request with the same headers.
The OAuth providers, however, use cookies for sessioning and do not require user invention for each auth. request. If you’ve approved a particular Facebook app, you won’t be shown any UI/UX or be prompted the next time that app requests your data – it will be invisible. When we do OAuth, we never have to send any user credentials to Facebook / Twitter / etc., because those are stored in browser cookies for facebook.com / twitter.com / etc. What we need to protect is a malicious party pretending to be a popular, valid Facebook app. and taking advantage of that short-circuit behavior that would get access to user data without the user’s knowledge.
My response:
So, how is that secured? If anyone can make a request to sign up from a
cordova webview (which comes from no specific url, just the app iteself)
then I can't secure from which url people can sign up from? So any site
could use our url "xxx.com" in their config and start registering
users?
That doesn't seem right to me.
I think I still need to have an external url that is whitelisted by you
guys. That would have the login form and do the auth.
But then my question is, can I transfer that auth back to my cordova app?
Is it somewhere in localStorage I can check? I'll have to run some tests.
And final response:
Sure thing – we’re happy to help. I wrote much of the original client authentication code, and can speak to the design decisions and rationale that went into it. Be sure to let me know if you have further questions there.
While we don’t store user passwords in cookies, of course, we maintain a Firebase auth. token in LocalStorage. Our authentication tokens are signed by your unique Firebase secret (so they cannot be spoofed), and can contain any arbitrary user data that would be useful in your security rules.
By default, and when using the delegated login (email + password) service, these tokens will only contain a user id to uniquely identify your users for use in your security rules. For example, you could restrict all writes or reads to a given path (e.g. write to /users/$uid/name) by the user id present in the token (“.write” = “$uid = auth.uid”). Much more information on that topic available on our website.
Your plan to spin up a server to authenticate users with Amazon and generate tokens sounds correct. This is a common pattern for our users who wish to use authentication methods that we don’t support out-of-the-box (ie Amazon OAuth) or have custom auth requirements. Note: once you’ve created those tokens and sent them down to the client, they’ll be automatically persisted for you once you call ref.authWithCustomToken(…). Subsequent restarts of the app will use the same token, as long as it has not yet expired.
This is a topic of interest to me too as I have implemented something similar , twitter digits (native android) + firebase custom login in webview.
I think, as recommended by firebase, you can use other authentication providers and then the firebase custom login.
Do you use the Amazon login in android native code ? If so after login, then generate a JWT token for firebase and use it to access firebase.
If all code is in Html/js app, then maybe you can use custom login and generate a token on your server after making sure its logged in to the Amazon.
The trouble with Android hybrid apps is the following: the JWT token (for firebase) should be created on secure system (eg. server side) not with android java code, other option for hybrid app is to do a http request to generate the token, but I find that less secure, anyone would be able to get a token by finding the URL, than I resort to generate token within android app code, you can change security key/seed for token when doing new releases.
In summary, I don't think firebase studied the problem of mobile hybrid apps.

How to implement a web widget with OAuth 2.0

I want to create a web widget that will display information from my site.
The widget will be included in the client's website HTML using JavaScript, and should only be usable for my clients -- web sites that were registered at my site.
The information in the widget should be specific to the user who is currently visiting the client's site.
So, I need to authenticate both the client (website owner) and the resource owner (website visitor). This seems to map nicely to OAuth 2.0, but I couldn't find a complete example or explanation for such an implementation.
Any resources or pointers to such information will be appreciated.
Update: I've stumbled upon this article, which provides an outline for an approach that uses OAuth. However, it is not detailed enough for me to really understand how to use this with OAuth 2.
There are many large organizations that have done this, and I'm sad to see no other answers for this question since it's such an important web pattern.
I'm going to presume that you are not rolling your own OAuth 2.0 provider from scratch, if you are - well done otherwise you should be using something kickass like Doorkeeper to do this for you.
Now, in OAuth 2.0 you have the following entities:
Users registered on your website
Applications registered on your website (who subscribe to your oauth2)
User Permissions which is a list of Applications that a user has 'allowed'
Developer (who is consuming your auth API / widgets and building an Application)
The first thing to note is you must have a domain name associated with each Application. So if a developer registers for a API token / secret on your website, the Application he creates is mapped to a unique domain.
Now, I presume that the flow for an application to authenticate users via your website is already clear. That being said, you don't need to do much for this to work.
When an Application sends the user to your website (in order to sign in) you place a session cookie on the user's computer. Lets call this "Cookie-X".
Now the user is authenticated by your website and goes back to the Application. There we want to show a custom widget with information pertaining to that user.
The developer will be need to copy paste some code into this app.
The flow is like this:
The code will contain a url to your website with his Application ID (not secret) which he got when registering his application on your website.
When that code runs, it will ping your website with his appId. You need to check that AppID with your database, and additionally check that the referrer url is from the same domain as that which is registered in your website for that AppID. Edit: Alternatively or additionally, the code can check for document.domain and include it in the ping to your website, allowing you to verify that the request has come from the domain that has registered with the given AppID.
If that is correct, you reply back with some JS code.
Your JS code looks for the session cookie your website had set when the user had signed in. If that cookie is found, it pings back to your website with the session and your website responds with the custom view content.
Edit: as rightfully mentioned in a comment, the cookie should be HttpOnly to safeguard against common XSS attacks.
Additional Notes
The reasons this is a secure approach:
The AppId and domain name are a good enough combination to verify that other people are not fetching this information. Even thou the appId is visible in the applications html source, the domain name would have to be spoofed by anyone attempting to use someone else's AppID.
Presuming someone takes an AppID which is not his, and writes code to spoof the domain name of the referrer when requesting for your widget, he still won't be able to see any information. Since you are showing user specific information, the widget will only render if your website can find the session cookie it placed on the users browser which can't really be spoofed. There are ways around like session-hijacking, etc. But I think that's beyond the scope of this question.
Other Methods
Just by looking at Facebook's Social Plugins, you can tell that there are other options.
For example, one might be to use an Iframe. If you ask the developer to add an Iframe to his application, you can even reduce a few of the steps mentioned above. But you will have to add JS along with it (outside the iframe) to grab the correct domain, etc. And ofcourse from an accessibility and interface standpoint I'm not very found of Iframes.

PhoneGap and OAuth2

I am developing a PhoneGap application and require my users to sign in through Google with OAuth2. Is this possible directly through JavaScript? I have almost no experience with JavaScript (and jQuery).
What are the options? I have thought of a cumbersome alternative which involves posting the username/password to an application I have hosted on a server which then takes care of logging in. Then the PhoneGap app will have to ask the server if the authentication was successful. However, I was hoping there would be a simpler way.
What is the best way signing in through Google on a PhoneGap app?
I have managed to get it working! I'm posting my thoughts here because I had a hard time finding the answer after hours of searching the web.
The important steps are:
Make sure ChildBrowser works properly
Setup a function that will listen to page changes
window.plugins.childBrowser.onLocationChange = function(fooUrl) { console.log(fooUrl); }
Build the URL with the query string as described in this tutorial
Point ChildBrowser to the URL
When the user logs in, you will be able to extract the session token from fooUrl
If you still don't know how to do this, have a look at this Android app.
(There is a lot of code, and it might seem overwhelming, so I suggest only going for this as a last resort)
Google will not allow you to perform direct authentication by handling the user credentials directly. Instead Google wants you to perform an authentication protocol, typically OAuth 2.0. Other popular authentication protocols you may hear about is OpenID 1.0, 2.0, OpenID Connect, SAML 2.0, ID-FF, etc. These protocols will redirect the user to the Identity Provider (Google, in this case), and send you back with an assertion that you may use to trust the user. With APIs, like Google, you would make use of the authorization functionality of OAuth, which provides you with a token that you may use with all Google APIs after authentication.
A good introduction to how OAuth 2.0 works
With PhoneGap and mobile apps, things are a bit different than the typical OAuth setup.
In your case, the browser is in a controlled environment, your app, and you may
select to redirect the user to Google Authorization endpoint using the main view,
select to open a ChildBrowser with the Google Authorization endpoint, to not lose any state on your app.
to somehow open Safari or another browser with the authorization endpoint, and register a custom schema handler, to redirect the user back to your app after authentication.
These examples are vaguely mentioned in the OAuth 2.0 specifications, but there are no aid in what is the best or optimal in a specific use case. Often the best possible option is not perfect (from a user perspective).
I recently wrote a tutorial on how to make this work with Phonegap and ChildBrowser for iOS.
OAuth 2.0 Guide for Phonegap using ChildBrowser and JSO

Categories

Resources