Our app has an OIDC provider and for our users, we use the standard OAuth redirect flow since user authorization and authentication are performed on the same device. However, now we have mobile users within our app we want to extend authentication to the app.
I've been looking a OIDC CIBA flow and not sure if it is right for us and I wanted to make sure.
During the verification/authentication stage of OIDC we traditionally display a login screen. However, I am thinking for mobile use cases we can just show a "polling" screen to indicate a back channel request has been made.
Since we have the device token (through a pairing phase at some point before) we can send a push notification to the phone and ask the user to approve the request. Using mTLS for encryption I can ensure a secure connection to the device. The polling screen will poll an API by a UUID for the result (the mobile device will make a success API call after approval). Once it has the result it will redirect the user back to the OIDC redirect flow.
This means we don't need to introduce CIBA and just have a new verify screen that will perform the async work then redirect once done.
There may be a couple of use cases you are mentioning here. For each I would aim to follow the most standard solution, with simplest code in apps and best options for extensibility.
WEB APP LOGINS ON A DESKTOP
Sometimes a login in a desktop browser involves a mobile device, eg if I log in to gmail in a desktop browser I am prompted to confirm that it's me on my mobile device. This triggers a call to Google's APIs, and meanwhile the login screen polls the same APIs, to detect completion.
MOBILE APP LOGINS
Extending the flow to work for mobile should work in the same way. Gmail uses the AppAuth pattern from RFC8252 to sign me in, then presents the same prompt to confirm it's me. In this case there is no need to switch devices. Also of course the mobile login has no dependencies on the user having access to a desktop, so that authentication works in mobile scenarios.
CODE FLOW
Both of the above use the code flow, with multi-factor authentication. Passwords are the primary factor (something the user knows) and a Polling Authenticator is the second factor (requires the user to have ownership of the device). Once you are using the code flow, your apps support many ways to authenticate and the authentication workflow can be changed without needing to change at the authorization server without changing any application code.
MOBILE FACTORS
There are a few different types here:
Time Based One Time Password (TOTP): apps such as Google Authenticator ask the user to enter a 6 digit number which is calculated the same both on the device and in the authorization server.
Polling: The login screen polls the Authorization Server, which in turn polls an external system to see if the user login has completed, as in the gmail case above.
App2App: In some cases the primary authentication factor can be an external app. This type of solution is also implemented via the code flow, as explained in this app2app article.
CIBA
This is a different use case, typically used when User A needs access to some of User B's resources temporarily. The classic case is when a call centre operator needs to act on behalf of a user. The call centre app then triggers a flow that results in the remote user being prompted to sign in. See this tutorial and video for an example. It does open up some interesting possibilities, such as delivering tokens via push notifications.
SUMMARY
Implementing a mobile login by getting the user to provide something they know on a desktop, then delivering a push notification, feels over complicated and non-standard. It might work against the mobile architecture also, eg preventing logins if the user is on a train.
I would favour the AppAuth pattern and implementing mobile logins in the standard way, by getting the user to provide something they know on the device. It is likely to provide the most secure behaviour and also the best all round architecture. If you have special reasons for wanting to do things differently, you should update your question to explain why.
Related
Note: This is the first time I'm trying to implement a social login API, so thanks for bearing with me and helping me out!
I am developing a web application and I have a login and registration system already developed. Now, I am thinking of adding Facebook and Google+ login - with a backend. I went through their docs and other tutorials and they require to implement considerably a lot of things.
But, since I have a registration system already, I thought of doing something like this:
Have the social login buttons on the login page.
When the user clicks on a social login button and authorizes the app, the user data is returned from Google+, for example.
Now, instead of proceeding with the OAuth procedure like getting the user ID, secret ID and contacting their server from my server for token verification and getting data, is it possible to just use the data returned (after the user authorizes) and do the normal registration with the registration system that I already have?
These are the advantages that I see in doing this:
No need of extra code or database fields like token ID, etc.
User can add a password to their account whenever they want and login to the site or access their account by logging in through Facebook or Google+ given that they use the same email ID.
It's enough to use the social login providers' API once - the first time the user logs in (which technically registers the user to the site).
I know the advantages are the same when following the full OAuth2 implementation, but what difference does it make?
Now my questions are:
Is it OK to cut short on the social login as mentioned above?
Will I be losing any obvious advantage doing so (given that I already have a registration system in place)?
If yes, is anyone else cutting short on the flow in their website?
The system proposed by you has certain flaws, especially security related flaw. I would give you to the point answer:
You will send data from client after getting it from google+ or other provider and use your registration process implicitly.
This approach is wrong as I myself as an attacker can send you the data from google+ using my clientid for an app. Will you register or login using the info I am sending? I can pretend to be anyone in your system if you do that.
Is it OK to cut short on the social login as mentioned above?
Will I be losing any obvious advantage doing so (given that I already have a registration system in place)?
If yes, is anyone else cutting short on the flow in their website?
No. (see the reason above).
No. You won't be losing advantage as you already have system in place. Most of the sites have a system in place for normal registration. They give oauth login by leveraging it. Some will say that the password is cumbersome or such, but all famous sites provide login and password including SO.
Now the question comes, how to simplify the oauth system given that you already have a system in place.
I recommend this(I would assume Google as a provider) flow with things starting with dot are what you need to do:
You have a Google login button.
User click on Google Button.
The User is redirected to the Google site.
The user gives you permission.
Google redirects and give you a token.
You can now send info and token to your server. (You need to send only token as backend will get info. Otherwise, a user with valid google+ token for your website can send you any info).
Backend verify token and match that "aud" is equal to your client id. Or it can happen via a library. You will need to give only your client id.
Backend get profile info from token in case of Google+(Name, email) while verifying which you can store as part of your registration process or login process if that email already exists. You can store google id of user also. This is useful as some provider like fb don't always provide email for every account. (For some fb don't give email but for majority of cases it give you the email.)
Backend send back session info or jwt token or any other time bounded process which tells that the user is login.
Your user can login via email also. If he isn't already registered then, then he will need to register. Otherwise, using forget, he can set password or from accounts settings he can set password.
You also need to be careful if the same user is connecting via a different provider, he need to have the same account in your system which you can handle via email.
Kevin,
Authentication is a complex procedure involving lot of measures to ensure security. Hence Web-application/ App developers, delegate this critical piece of work to Identity providers like Google, Microsoft, Facebook etc. These Identity providers are trusted by the app developers and more importantly the consumers trust them too.
Why do app developers provide third party/ social logins? Because, it gives the users of the app some advantages.
They don't have to create new account with the app and remember the new set of credentials. Instead they can use the same credentials they are using with the Identity provider, to gain access to the app. This is huge.
They don't have to trust the app completely, means how the sensitive information like passwords, security questions are handled in the app, as they are not providing any sensitive information directly on the app. Only needed public information is fed to the app from the Identity provider. This is huge too.
No need to worry about the system compromise and leak of sensitive information as all Open ID providers have better security policies in place. This gives consumers a high degree of confidence when using your system through third party logins.
"All the advantages you mentioned will be great for the app developers
at the cost of disadvantages to the consumers of the app."
Lets put the consumer disadvantages on the side and look at the advantages you mentioned:
No need of extra code or database fields like token ID, etc.
You still need code/setup to validate your own tokens. You have to add more logic to verify the external tokens, but the consumers will have the advantage of using the external providers like they are in any other application.
User can add a password to their account whenever they want and login to the site or access their account by logging in through Facebook or Google+ given that they use the same email ID.
This is little confusing as users may choose external provider, so they don't have to remember a new password. Also, the account validation process is different if you use external login vs id/password login. If you are willing to provide both, then you already have the system in place, to verify the account for external logins. Then your first advantage is void and you are better of using Open ID spec.
It's enough to use the social login providers' API once - the first time the user logs in (which technically registers the user to the site).
This approach adds confusion to the flow for consumers. They expect to see a login screen from third party provider for authentication (when they click on google+ or FB), but instead they see your login screen.
Instead of cut short approach, it would be worth to use the complete flow. You might add more logic to handle the token verification with external providers, but, actual complex logic of token validation is delegated to the external providers. This adds no confusion to the end user and they can trust your application easily through social id providers. Even though, users can authenticate through social Id providers, it is always a best practice to have the profile object of that user in your system (without the sensitive information like password).
Since you have your own registration process in place, this may not be a huge advantage. But, please look into the open source implementation of any of the Security Token Service (STS) providers, to see if you can borrow some of the features for validation external providers.
Please let me know if you have any questions.
Thank you,
Soma.
I'm planning introduce two factor authentication to my iPad application. Currently user login to my app using a username and password. That username and password is validate from the back end web server devloped using .Net. If user is authorize to login then he can access the iPad application.
Now I want to introduce two factor authentication to validate user. I want to know what are the options we have here. Since we have user’s phone no with us I was thinking of sending a passcode to his phone each time he tries to login to the iPad application. But iPad doesn’t support sending messages over the GSM/CDMA network. Is there a way to achieve this? (Thought about getting an SMS gateway from the local ISP and writing SMS a server. But it cost more) Third-party module will be ok.
Check google authenticator. https://code.google.com/p/google-authenticator/
I think it is quiet good for two-step authentication.
Here is source code for server side (it is on php but i think it is not big issue to convert it to .NET or another platform) https://github.com/chregu/GoogleAuthenticator.php
As I know it uses Time-based One-time Password Algorithm http://en.wikipedia.org/wiki/Time-based_One-time_Password_Algorithm
You can send an SMS to the mobile phone of the user with a code.
After that the user puts the code and the APP validates the code making a request to the server.
The SMS is sended after the user sucessful introduced the username/password.
Other option (less expansive) is to send that code by email.
You should try the google Authenticator
There are other's like https://www.gauthify.com, who offer this service.
You may be interested in looking in this StackOverflow Post.
I cannot fully express how much I am impressed by Twitter's recent TFA implementation, it is extremely convenient and (assuming they didn't botch the protocol) much more secure than many other forms of TFA.
Here's a description written by Wired.
But to summarize you activate a device for TFA and it generates a private (device)/ public (server) key pair. When you try to login after receiving correct username/password credentials the server sends a push notification to the application on any authorized devices encrypted with the public key and the application decrypts the nonce and sends the nonce back to the server and is given a session.
And of course as others have mentioned, there are prebuilt services you can use such as Google Authenticator, but they tend to be clunkier and there are concerns about SMS and TOTP security.
Two Factor Authentication means confirming something the user knows (their password) and something they have in their possession (like a physical key, a badge, or RSA key fob; the important part is it's a physical object other than what you are giving them access into). Sending a push of any kind to the iPad they are using to login to the app defeats the purpose and is no better than single factor (password only). Your only choices are:
Distribute an RSA key fob (or similar). Probably not an option because of the cost & management overhead associated.
Create an authenticator app that only works on a separate device than the iPad with your app on it (along the same lines as the Google Authenticator app). You can probably prevent the authenticator app being run on the iPad by registering a URI scheme for your protected app and trying to open it from the authenticator every time the authenticator is opened. If the protected app opens that means the user is trying to run both on the same device and the authenticator should not validate them.
Send a SMS to their registered phone with an authentication code. By using SMS here you're forcing the user to have both devices to be able to login, which is the key to TFA. Note that a creative user could register a Google Voice number (or similar VOIP with SMS app) on their iPad, thus circumventing the physical aspect of TFA.
we are developing an iOS App using Adobe Flex/Air. The app uses a web service that needs user authentication via facebook login. At the moment, we use server side authentication: There's a login URL displayed in a WebView where the facebook login is done. This way, we get an access_token that can be used on the server side.
This works perfectly but it would really be much better if we could use Single Sign-on with the facebook ios app. As far as I have read, this should work on the client side but I haven't found a way to authenticate the user on the server side.
facebook's access_tokens are valid either for use on the server-side or for the client side so an access_token from the client-side login won't work for the server side.
Thanks in advance for your ideas,
Henk
As far as I can see, you're making this far more complicated than it's really intended to be. Leverage the Facebook iOS SDK, and all of the heavy lifting involved with authenticating the user within your app is handled by the Facebook SDK. There's no need to independently provide sign-in sheets and manage access token exchange between the app's local storage and Facebook's servers without the convenience of the entire Facebook SDK.
This link shows you how to implement SSO natively within your iOS app. It's real simple.
http://developers.facebook.com/docs/mobile/ios/build/#implementsso
Then, I understand that you're keeping authentication information or central user database information on an external server. The best way to synchronize the information between the FB client and your own servers is to simply check the login information returned by the FB SDK with your server after you receive it.
Here's a simple breakdown:
Log the user in using Facebook's standard SDK (see the link above).
In the -didLogin method (or whatever the equivalent is in your Adobe AIR environment), check the access token returned by FB with your server. Not sure what server architecture you're using, but it's safe to say that this will go on outside of the FB SDK. Also, save the access token in your app's user defaults so that the user won't have to login again next time. This whole process should (and inherently will) feel much quicker than it sounds.
If the check with the server returns successfully, notify the user of a successful login. If not, display an error view explaining the reason the user was rejected/not logged in.
Why do it this way? The reason is fairly simple. It's safe to assume that the reason you're having a user login to your app via Facebook is so that you can make requests for the user's Facebook information (i.e. feeds, photos, likes, comments, etc.). The easiest (and best) way to do this is through the FB SDK its self. The SDK takes care of a lot of stuff behind the scenes like access token validation over time, extension of token life, validity of token, and so on. This way, you won't have to worry nearly as much about syncronizing the server information and real-time client information when changes take place. Just authenticate via the FB iOS SDK, and do the rest of your own processing afterward.
Comment below if there's anything I should clarify or even if I missed the point of your question entirely--I tend to get on a roll and may stray from the point. :)
Cheers!
The Kraken
I'm trying to work out the best architecture for a couple of apps I'm developing.
In both apps I want to utilise google/twitter/LinkedIn/etc to provide authentication of a users identity. The app is composed of an iOS app which has an option to send data to a server which I'm writing in node.js.
I want to utilise either OAuth or OpenId to handle identifying a user against the above servers so that I don't have to put in an authentication system of my own. In other words, allowing users to re-use their ids when choosing to upload data.
I should also note that apart from identifying a user, obtaining a name and email address, I have not intention of using any of their APIs at this time.
I think I have two options:
Place the Authorisation code in the iOS client and transmit some sort of key to the server with the data which it can then verify.
Keep the iOS client fairly dumb, and handle authorisation from the node server.
I'd probably prefer the second option because it means I could centralise authentication and be able to support a web site as well. That's my current theory.
Can anyone who has done something like this give me some pointers as to the pros and cons, OAuth or OpenId, or links to some examples?
In our previous app we opted for a combination of the two approaches. We wanted to centralize our user data on our server in the event we needed to make future API calls on those services. We also wanted the native oAuth experience for the user on the client. Ie: on Android and iOS, the developer can have single sign-on / authorization run through the native Facebook app (if available), vs. popping-up a webview that serves the 'Approve' dialog. It's a better user experience in my opinion. Also for Twitter, the oAuth process may require a PIN code to be entered in the callback which should probably be handled on the client side.
You can pass the access token retrieved by the client to the server for storage and later use if you intend on making additional API calls on these services, provided you expect the token to be long-lived (ie: offline-access permission on FB).
In any case this is mostly a user experience decision.
I asked various questions about my problem (here and here) and I also asked in the #oauth & #openid freenode's channel on IRC. (this is note an "UP" question, it's an other problem)
I'll sum up my project configuration : Anyone will have the possibility to create an app that can use my API. To start, I'll work on my API and a Web based app, but the documentation about the API will be public. It's a bit like Twitter API.
The problem I face is how can I be sure which user is using the API (to retrieve his personal data, like your tweets), even if the User is using an app that I don't know who make it (again, like twitter and all the apps around).
I googled a lot and with the help of the previous answers given, I took a look at OAuth.
As far as I understood the way OAuth works, here how :
A user visit an app that use my API (web, mobile, whatever)
The apps redirect the user to the API for the authentication (I'll use OpenId) and the authorization (OAuth). This is a bit odd since the API will have a web interface for the login and the authorization (I suppose this is how it works since Twitter do that)
The API redirect the connected user to the app, with some tokens. In these tokens, there is a token representing the user that the app must store in order to indicate to the API which user is using it currently (Am I correct?)
So far, everything goes well. But what I can't figure it out, is when the user quit the app and goes again : how the app can remember the user is the one that used it before ?
(Before some of you bring me the cookie answer, I'll remark this is a simple example, it would be the same if the user clear his cookies, format his computer or change its computer.)
The only solution I can find, is when an unauthenticated user (without a remembering cookie for example) goes to the app, the app redirect him again to the API to authenticate himself, but this time, the user won't have to re-allow the app (authorization) since it already did it. The API will then return the user to the app to allow him to play with this.
Is this the proper & secure way to do it ?
The #OAuth IRC channel told me about the new protocol, WebID, but this is currently in pre-draft mode and I don't want to use something that will change continuously in the future :/
Thank you very much for your help!
Short answer: OAuth results in an authenticated access token. That access token is tied to ONE user. And as long as the access token is valid. The third application can do whatever the API allows the access token to do.
Long answer:
The thing with OAuth is that it does not "Log in" a user. OAuth gives third party applications what is called access tokens which can be used to access data on behalf of a user whether he/she is logged in or not.
Many services restrict their access tokens. Twitter for example issues two types of access tokens, read-only, and read/write. But there is no concept of logging in to use APIs. While an access token is valid, a third party application can access the user's data, and change things without a user's explicit interaction.
Most API providers have functionality to revoke access tokens. That is what happens when you in twitter look at your Connections page . See the revoke access links?
Personally I love the OAuth approach. As an API provider, you can control what access tokens are allowed to do, and the user can kill bad applications from using his/her resources. OAuth is secure as far as authentication goes. Third party applications do not get hold of user's passwords. But once authenticated they can do whatever your API allows.
if we take a look at how Twitter works, I think the missing point is an other layer to the project: The Official website:
The thing is, when you want to allow any 3rd party application to use Twitter, this application redirect you to the OAuth page of the Twitter API, IF you are connected, but if you aren't, it redirect you to the login page, which is located at http://api.twitter.com/login
(I don't know if keeping the api in api.twitter.com for loging an user, instead of just twitter.com is correct, but this is just semantics)
So, the workflow would be:
A user goes to a 3rd party application (like a website)
This third party redirect the user to the API for Authorization
The API redirect the User to the website for Authentication first
The official website redirect the User to the OpenId provider (or Facebook connect)
The Authentication is made (via multiple requests)
The website redirect the user to the API after he's successfully authenticated
The user allow/disallow the permissions asked by the 3rd party apps
The API returns to the 3rd party apps.
The User can now use (or not) the application.
This implementation have 2 problems:
Every time an User ins't authenticated (cleared it's cookies, connect himself from an other computer, etc), he will have to go through the Authentication method, by being redirected to the Official website and then being redirected to the 3rd party application (the API would be transparent, since it has already allowed the application to access his data).
All those layers would certainly lost the User on the Authentication process with too many redirections.
A possible solution would be to store the user's access_token, for example in the case of a mobile app, but with a pure html/css/js oriented app, this isn't possible. A login/password in the 3rd party web application that would match the user to the access_token of the API would be an other solution, like Seesmic (I think), but this is just useless (for us, not Seesmic) : the idea of not having the user's password become useless.
This is a possible explanation but I would require more details on how this is possible and your thought about that solution. Would it work?
(I added this as an answer since it's an (incomplete and not so sure, I agree) one.