Node.js Provider auth (oauth, OpenId) with SPA or mobile app - authentication

I have :
a backend app, done with sails.js.
a mobile application, done with ionic framework.
I would like to accomplish :
give to the users, on my login page, the opportunity to sign-up/sign-in with facebook, twitter, google, and "local".
on my server, I'd like to have a single collection of users, registred, with both local users and provider-authenticated users.
My primary goal, through this question, is to understand the multiple strategies and concerns of provider-authentication inside SPA (be a web app or a native mobile app). I've read many things about 0Auth, OpenID, client-side auth vs server-side auth, session based auth vs token based auth... I just don't get it. There is too much information out there about this and I'm pretty lost.
What are the possible flows ?
I think I got that I can authenticate with both OpenID and 0Auth, but which one should I use ?
On mobile, can I authenticate with "the facebook app" instead of using a web endpoint ?
I usually hear about "callbacks" after auth, what about them in a mobile app, where there is no web-server ?
NB: I'm not directly looking for implementations or libraries (like passport or sails-auth). I'm looking for an explainations of the different approaches and flows. Though, I'm open to discover some libraries as examples of the words

Related

IdentityServer4 External Authentication without cookies

I'm having trouble understanding how ASP.NET Core authentication works.
I want to implement JWT access token authentication with refresh tokens. To my knowledge, this is the industry standard for authenticating a client (Mobile app, SPA Web application). For security purposes, I'd prefer to not implement my own authorization logic including JWT generation and refresh token handling. Since ASP.Net does not natively support this, Naturally my choice would be to use IdentityServer4, a large open source library for handling this kind of stuff.
However IdentityServer4 is heavily based on OAuth, and I'm not sure how that works with SPA applications and mobile apps (clients I trust). It requires the client to redirect to some arbitrary webpage to enter their credentials and then redirect back to the app. Gross. I've never seen a major app like Snapchat, Instagram, etc. have this kind of authentication flow where you are directed to some webpage/browser during the login flow. Luckily IdentityServer4 has a little feature to handle username/password authentication for my trusted clients (http://docs.identityserver.io/en/latest/quickstarts/2_resource_owner_passwords.html)
Great, that seems to suit my needs. But... Now I want to add Facebook Authentication. IdentityServer4 allows for External Authentication, however it is still cookie based (to my knowledge). Which requires the Android/iOS/SPA app to redirect to a webpage and then redirect back to the app. Again, this isn't ideal from a user perspective. Facebook provides native mobile SDKs to handle this type of authentication which returns an access token so there is no need to redirect to web pages using cookies.
Now lets say my iOS app uses the Facebook SDK to grab an access token for the user and sends it to the backend. The backend validates the token against the Facebook SDK, and subsequently registers a local user in it's own database.
Now when that same iOS user tries to login to the app, the app will generate a facebook access token for that user from the SDK and send it to the backend. However I'm not sure how to utilize IdentityServer4 to generate a JWT for the user since I need that users' username and password. This is where I'm stuck. I seem to be fighting against the library which makes me believe I am severely misunderstanding something.
TLDR; IdentityServer4 seems to be heavily based on cookies which doesn't really fit nicely into mobile apps/SPA webpages when you are redirected back and forth from authentication webpages. Am I using the wrong tool for the job? What are some alternative solutions?
As a note on big social apps: I think it comes down to who keeps the passwords. Facebook, Instagram, Snapchat, Google act as identity providers to third parties. They themselves require user to register and specify the password which they keep. Therefore they can use any customized approach for handling validation with those passwords. However, if any of them offerred a posibiltty to log-in with the other I.e Instagram were allowing to sign-in with Amazon credentials, then they would need to follow through a standard way like OAuth and redirect to the third party for log-in. Last time I checked Instagram, Facebook and Snapchat only offer to register and no option to sign in with 3rd parties which explains why the don't need redirects.
Now if we establish that a redirect is a necessary evil, then the means to carry over the data accross aren't that numerous. I.e. we either would need to pass data via a query string or use cookies. Am I missing any others?
Both have limitations but since cookies are persisted and browser carries them automatically with each request, they do seem like a better option for the job, especially if multiple redirects are required for an external IdP to track the state of authentication request. The same reason is mentioned here:
http://docs.identityserver.io/en/latest/topics/signin_external_providers.html
It's absolutely the right tool for the job if you want what OpenID Connect and OAuth2 give you. It sounds like you may need convincing though and it may be that your use case doesn't need the full breadth of functionality offered.
If you have multiple client applications and APIs in play then I think using OpenID Connect and IdentityServer4 the right choice at this point in time.
Regarding native apps, you used to word "gross" to describe using the user's default browser to perform the sign in process and it's understandable why you might think that at first but it's not as bad of a UX as you'd think and has plenty of advantages:
The client application is completely decoupled from how authentication is actually done be that federation, social sign in (Facebook in your case), multi-factor, retina scan etc. Your identity server deals with all that complexity and is a single point of management (and failure - so make it highly available!)
Single sign on is possible - if they're already signed into your IDP then they can go straight in (although you have full control of the flow - want them to consent or confirm the sign in request every time - you can do that)
If the user has a password manager set up in their browser then that'll work too
Both iOS and Android offer APIs for doing this stuff and the work well. If you skin your native and web UIs to look similar the flow from a user's PoV is not jarring at all.
You can still use refresh tokens (ultimately secured by the platform) so you don't actually have to do the interactive flow very often anyway.
Some additional reading below. Quite a lot of thinking has gone into this from the industry so it's definitely worth digesting the current best practice.
https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html
IETF current best practice: https://www.rfc-editor.org/rfc/rfc8252
Don't make Scott hate you ;) : https://www.scottbrady91.com/OAuth/Why-the-Resource-Owner-Password-Credentials-Grant-Type-is-not-Authentication-nor-Suitable-for-Modern-Applications
For client side SPA browser apps OIDC provides the implicit grant type and uses a silent refresh and IDP session monitoring mechanism to maintain the session. Check out the oidc-client-js library which implements this approach.

Best practice for first-party auth in a native app

We have an auth infrastructure based on OAuth2 that is integrated into a variety of web apps within our organization. We also have a pure native application with no middle-ware of its own, and we want to integrate authentication into this native application. This application already has its own internal login mechanism with a native login screen, and we don't want to have it start launching external components like web browsers in order to display login windows. We are both the app provider and the auth provider, so the concern of the app having visibility into the user's credentials is less of an issue -- we trust ourselves to not intentionally do anything untoward with the user's credentials, and it's the same people writing a login form in the app as writing it on a web site. :-)
We are trying to figure out how best to support having the application continue to collect credentials the way it does now, but use them to obtain an auth token within our auth framework. With the APIs in place right now, the only way I can see for it to be done is to bake a Client Secret into the native app so that it can use a Resource Owner Password Credentials Grant request, since the code that would normally be making this call doesn't have a server side to live in. This feels really wrong, somehow. :-P
As far as I can see it, many of the structures of OAuth don't really apply to this app because it's not living in the context of a web browser, it doesn't have any concept of a "domain" nor any sort of "cross-domain" restrictions. It has been suggested that perhaps we create middleware for this app just for the purpose of exchanging authentication codes for tokens, but the rationale for that seems to be that this middleware theoretically ought to be able to somehow vet requests to determine whether they are legitimately from the application, and I don't see any way to do that that couldn't be faked by anyone with access to the client application code. Basically, the only purpose such middleware would serve would be to make the Client Secret irrelevant with respect to getting auth codes for credentials.
One thought that came to us was, how does something like Windows do it? Windows very obviously uses a native login form, but then some flow exists whereby the credentials that are entered are used for authentication and presumably, deep in the internals of the OS, for obtaining an auth token. Does anybody know if this architecture is documented anywhere? Does Microsoft's architectural choices here have any relation to OAuth2? What is the "best practice" for an application if you take it as a given that it doesn't have middleware and has its own native login form?
FWIW you don't need a client secret to use ROPC Grant to obtain or refresh tokens if the client is configured as a public client, i.e. a client that isn't capable of storing a secret.
RFC8252 OAuth 2.0 for Native Apps encourages using a native user agent for your scenario, using authorization code flows with PKCE. Authorization services like Okta and Auth0 have jumped onboard too, although they still recommend ROPC if the client is "absolutely trusted".
RFC6819 OAuth 2.0 Security discourages ROPC, but also says "Limit use of resource owner password credential grants to scenarios where the client application and the authorizing service are from the same organization", which are first-party apps.
So while the security verdict seems to be that authorization code+PKCE is the best practice, the UX hurdle of showing a user a browser window to log into a native app seem to be keeping ROPC alive. It's difficult to tell if that UX is jarring because people aren't used to it or because people can't get used to it.

Is there a classical way for securing a SPA and an API using Google Cloud App Engine?

I’d like to use the Google Cloud App Engine to serve a SPA and a REST API, both secured behind an authentication wall.
Is there any recommended way of doing this?
So far, I’ve found tutorials on how to secure an API, but not an SPA. Both ends are served from different projects, but I’d like to have a unique authentication step.
Typical flow would be:
Before serving the SPA source code, ask for authentication
Once authenticated, serve the SPA and allow the SPA to access the API resources
Thank you!
So far I’ve reviewed the documentation, it doesn't seem like there is any specific recommended way to authenticate an SPA within Google Cloud.
However, I think a pretty secure way would be to authenticate your application using the Toolkit Identity API of Google. The procedure would be to call this API from App Engine as the first necessary requirement.
This method works with Oauth2 access tokens. I think you could request for authentication credentials to your users before launching your application and granting access to the other resources/APIs.

Linkedin: Registering Application for both Web and Mobile

My project deals with both Web app and Mobile app. So before we can use Linkedin API's into our project we need to register our app with Linkedin according to this Quick Start. But for my situation where i use Linkedin API's for both web and mobile, Do i need to register two application with Linkedin. Or is there any other way to register a single application and use the same for both web and mobile?
In the registration page i don't see any distinction for Web and Mobile, unlike facebook where a single application registered can be used for both web and mobile app.
If anyone could point me to appropriate docs or pointers, it would be really helpful.
Thank you.
When a user authorizes your LinkedIn Application, their authorization is tied to that particular API key - if you were to use multiple keys in a single user realm, the user would in theory have to authorize both of them.
In short, I don't see any advantage to using multiple keys if your users are going to be exposed to both web and mobile.

Security in WebAPI App with MVC Client OpenID / OAuth

I know there is a lot of questions out there already and I've been reading blogs and looking at samples for well over a week and I'm still a little hazy on how some of this is going to work in the real world. The samples are very helpful, some are very complex some are simple, none have really clarified some of my questions.
The system comprises:
Web App (own IIS site, with SSL, consumes Public API)
Public API (own IIS site, with SSL)
Desktop Widget
Mobile (iOS, Android)
3rd Party apps
How best to handle user registration and account creation? Whilst offering OpenID there also needs to be a 'local' login to the web application. Having a method on the API that accepts base data types (strings/dates etc...) values and then creates an account is asking for trouble and a red flag to the spammers. Would it be best to handle this exclusively through the web site employing visual CAPTCHA checks? How does the Facebook mobile app handle this registration scenario?
Lots of samples also seem to use small subsets of the default Forms Authentication database for Membership. They then use Entity Framework and the Membership, WebSecurity or FormsAuthentication, Roles Provider classes in various different ways depending on use case. Are there any alternatives to this approach to consider for the security backend? Our DB guy is considering rolling our own but then we also need to build our own user management app :(
Once a user is registered and logged in to the web app I can't see any way around continuing to authenticate and authorize each call on the WebAPI. I'm assuming at the moment that the API should just implement OAuth and treat the web app as another client app like the mobile app and 3rd party apps.
I think I've read too much without playing with code to settle this in my head. There are so many approaches.
TIA,