Which is the better way to implement authentication using login/password AND other social networks? - api

I'm gonna try to explain my problem :
I'd like to allow users to connect to my api via their own accounts (login/password) or via a social network (Facebook at first).
Then, I would allow any application to use my api, with the user authenticated.
My first thought when to auth the user via his/her login/password and return a token used as the session for the next requests.
But OAuth would seems to be the better implementations, except I don't know how to do this :
One of my applications will have to connect via login/password, like twitter web (I have to implement an login/password auth somewhere if I wan't my user to login :p)
Will I also have to register my applications to the oauth system (did twitter added their web app to their oauth ?)
How to merge the auth via others social networks. Concretely, the user will have to OAuth to my api that will auth to the social network.
I'm a bit lost on how to do this, if someone could help me, I would really appreciate !
Thanks
Update 1:
Flickr and Lastfm seems to not use OAuth but an alternative auth system that looks like this :
The user is redirected to Flickr/Lastfm
The user auth himself and accept to use the application
Flickr/Lastfm return to the Callback url with a temporary frob (for flickr) or token (for lastfm)
The app must call the provider with the temporary frob/token (among with the api_key and the api_sig, as always) and get in return the session token to use for the next calls.
Update 2:
In fact, StackApps is the concrete case of my problem : you can login through their login/password system OR openId, and you can use their API.

OAuth is only needed to make others use your API on other services, i.e. authorize services to use your API without users of the intermediary service explicitly having to log in into your service by giving user's login credentials to a third party.
What I think you need is OpenID, the cross-application authentication mechanism. You just need to implement an OpenID client, accepting third-party OpenIDs to authenticate users, to subsequently identify them, when they use your service's API. This would have to be supplemented with a normal 'local' user authentication mechanism (i.e. login/password entry page)
You will need OAuth to provide an ability to use your API on other sites, though.

Related

SSO with JWT and multiple user accounts + SPA

I have two web applications app.domain1.com which is a SPA with his own API on api.domain1.com and app.domain2.com) with each have their own authentication system and user accounts
and I need to authenticate the user from app.domain1.com from app.domain2.com. The goal is to simplify switching from one app to another without requiring the user to log into each application by re-entering their password. I'm the owner of one app only so It's not possible to put them behind a reverse proxy or so.
Example :
app.domain2.com redirect to app.domain1.com/connect/{JWT} -> app.domain1.com SPA extract the JWT and send it via ajax to api.domain1.com for validation and login.
I have looking for OAuth2 and OpenID Connect for these but OAuth2 is more about delegation of resource access than authentication and OpenID Connect needs an Identity Provider which seems incompatible with my use case where each app has his own authentication mecanism and where I could not add a central authentication server.
Ideally, I'd like to adhere to a standard protocol.
I thought I could expose an endpoint GET /connect/{JWT} on each app.
The JWT could contains an email which could identify the user account, app.domain1.com and app.domain2.com could then share the secret for validating the JWT has not be tampered
and could have a short validity duration.
This endpoint validate the JWT, verify if a user match the email inside the JWT and log the user in.
I'm not sure about the security considerations with these process and if there is any other options ?
Thx for your help.
In my opinion you should go with OIDC. That protocol is designed exactly for the feature you described here. You can have one of the apps act as the IdP, and the other will be a Relying Party. It depends on which technology you use for your apps, but in some languages there are libraries which will turn your app into an IdP.
You can think of some generic protocol to make that federated login work, but you will be better off using standards. This way you won't have to wonder what are the security implications for your solution - you have security considerations for OIDC described in the spec itself.

Using Google's OpenID Connect as part of a SSO

I'm developing a common auth service for several different web services. The general idea is that a user goes to one of these web services and clicks on a login button and gets redirected to my auth service. Once authenticated, the auth service redirects the user back to the original web service.
To begin with, the auth service will use Google's OpenID Connect service. One idea I had was that when a user was authenticated using Google I could pass around the resulting JWT to other services to use as an auth token. Google mentions this idea in their documentation (https://developers.google.com/accounts/docs/OAuth2Login#validatinganidtoken):
One thing that makes ID tokens useful is that fact that you can pass them around different components of your app. This can be helpful because different components of your application may pass the ID token between them and use it as a lightweight authentication mechanism authenticating the app and the user.
Can anyone help me with the actual details on how this should work e.g. How do I handle log outs both on Google and from the auth service? There appeared to be some documentation on this in older OpenID Connect Session documents (-03) but it appears to have been removed.
You should not pass the ID Token that you receive to Google back to the app to use as an auth token. The ID Token will have an audience specific to your app, not the ultimate client.
If you just passed this back to clientA, then you would open it up to auth attacks where clientB could obtain an Google ID Token via your auth service and then use that token to gain access to user data in clientA.
A much better approach would be to mint your own ID Token and provide an audience designation for each app that uses your service.
Monitoring session state is not as straightforward. The easiest thing to do is for your service to wrap G+ sign-in libraries and interface with the session state api's.
https://developers.google.com/+/web/signin/session-state

Using oAuth (Twitter, LinkedIn) for login to a web app

Should I use oAuth, for example LinkedIn or Twitter, as my signin mechanism for my app? It seems that most apps just use oAuth to connect other services to it, but they make you set up your own user/password after you use oAuth (including StackOverflow), and I'm not really sure why this is. Would love some insight here. Thank you.
Why not use OpenId, to allow people to sign into your application, without having to type any specific login/password ?
Quoting the corresponding wikipedia entry :
OpenID is an open, decentralized
standard for authenticating users
which can be used for access control,
allowing users to log on to different
services with the same digital
identity where these services trust
the authentication body. OpenID
replaces the common log on process
that uses a login-name and a password,
...
BTW, that's exactly how one logs-in on stackoverflow ;-)
OAuth purpose is not authenticating your users with your site, is letting your users allow you (the oauth consumer) access to their protected resources in other sites (oauth providers) like LinkedIn, Twitter, Google APIs etc.
For authentication, you should use OpenId as others have pointed
Twitter provides a Sign in with Twitter flow that is OAuth but provides a faster redirect if it is an existing user of your service and they are already authenticated with Twitter.
http://apiwiki.twitter.com/Sign-in-with-Twitter
If you are building a Twitter centric application this makes a lot of since to use and you won't have to implement an entire alternate authentication method like OpenID.
Be careful if you let users authenticate with both Twitter and LinkedIn as users will inadvertently create two accounts and need them to be merged.
Facebook and Twitter both have the "Login with Facebook/Twitter" APIs to actually allow users to login without having to create an account for your website. Both of them will return you a valid session that may (or may not) expire. So you actually wouldn't have to ask users to decide on a username/password, as you can fetch both from the APIs (you can not get the users email address when using Twitter though)
So why add those functions to your website?
Users are in general more likely to hit the "Login with ..." button than going through the whole mail address authorization process and entering their name, etc...
Linkedin only has OAuth for usage to its API. It will also depend on what type of language you are writing your webapp in, they should have premade wrapper libraries you could tap on to.

Oauth authentication with a known user?

Most Oauth implementations require the user to login with the originating site in the process.
An example is: http://code.google.com/apis/accounts/images/OAuthDiagram.png
What if I want to use my own account to access a generic feature, such as a search for people outside of my network, and don't want them to login? Is there any way to login with my own generic account?
I am creating a web service that interacts with many social networks by searching them, so by forcing the user to login several times to each network if I want to use their API is just bad user experience.
You could try to authenticate your account manually and then store the access token. Any subsequent request would be made with the stored access token.
There are several problems with this approach:
if the token expires, you have to reauthenticate
you might run into request quotas if you do all requests from one account (e.g. Twitter)
If possible, I would use something like HTTP basic auth to authenticate to the services.
When you are strictly speaking of OAuth, it is not meant for this scenario. Try looking into SSO (Single Sign-On).
OAuth can also be implemented in conjunction with SSO solutions.

OpenID authentication and API access

OpenID authentication is inherently browser based. If I wanted to allow an OpenID user to authenticate against an API for use in alternative clients, is there an accepted best practice for that?
So if a user tried to log in with their OpenID into an iPhone app, for instance, how would that work? The only thing I can think of generating an API token of some sort for them and get the user to manually enter it somewhere. This approach is not user friendly.
This is the way sites like Basecamp work, but it still seems clunky to me.
The problem you're seeing is not unique to OpenID. Any password-less authentication scheme can have this problem. OAuth (http://oauth.net/) is a solution that is an open standard that is quickly gaining traction on a lot of web sites. It is totally independent of how the user authenticates, so their OpenID Provider does not need to support or even be aware that your site (the "service provider" in OAuth terms) is using OAuth. Your API client can be web based or even a local application!
The process would be something like this:
Roles:
the user: someone who has an account with your web site.
service provider: your web site, which has a programmatic API that requires some credential to access.
consumer: the client, whether web or local application, that needs access to the service provider's API.
Flow:
The user is at the consumer. He indicates he wants to access data at the service provider.
The user is either redirected (if the consumer is a web site) or a browser is popped up (if the consumer is a local app) and the user sees the service provider web site.
The user is either already logged into the Service Provider via a persistent cookie, or the user must first log into the Service Provider however that is done (OpenID in your case).
The Service Provider then asks the user: "Consumer (some consumer) wants access to your data (or our API, or whatever). Do you want to authorize this? (yes/no)
User confirms, and the browser window closes or is redirected back to the Consumer site.
Via some OAuth protocol magic, the consumer now has a secret credential that it can use to access your API and access whatever user-private information you just authorized.
Obviously I can't include the whole OAuth spec here, but you can see hopefully from the above that this should solve your problem. OAuth libraries exist to make adding support for it easy.
If you happen to be using ASP.NET, I suggest http://dotnetopenid.googlecode.com/ as it recently added OAuth support (v3.0 beta 1).
Neither OpenID nor OAuth define how a user authenticates. They define how the consumer directs the user agent to the authentication provider, how the user agent is directed back, and how the consumer can verify the identity that the user authenticated as.
The actual method used to authenticate is out of band for both schemes.
There are differences between OpenID and OAuth, but both require that the consumer use HTTP redirects and callback URLs. They're both browser based. If your app speaks HTTP, it can do either. However, a main point is that the user is only entering credentials into a trusted app.
What you want is not possible with OpenID. OpenID is based on the premise that you (the iPhone app) only want to know about your users that their OpenID-provider trusts them. They never authenticate themselves to you.
Good OpenID-providers in fact even prevent that you mediate the authentication process (as this would expose users to a possible attack - by you!): they demand that users login with them directly and refuse login-by-referral.
See: this related question
The problem is that the openid spec has no standard provision for authentication with the provider, so the provider can elect that authentication happens via a phone call or whatever.
Hopefully more providers embrace OAuth. Alternatively you could hand code the authentication for a few of the bigger sites.