I have been working on implementing OAuth in my project's API. As a part of this project, we have a mobile app that authenticates a user via this API, using a password grant (this grant actually sends the given credentials on to an upstream authentication server that doesn't implement OAuth - so it is required).
This mobile app also has the functionality whereby it opens a webview to some pre-determined websites. The idea is that these websites would be able to authorize on behalf of the user using the authorization_code grant.
This is where my question comes in. When authorizing the websites, we obviously require that the user be authenticated with our API. However, the user authenticated via the password grant in the app, and not in the webview.
How would we transfer the authentication from the app to the API when the authentication was done in the app? My thinking is that setting a cookie containing the token on the API's domain would be the best way of implementing this?
Apologies if the question is not as clear as it could be. I'm struggling with how best to phrase and explain my question.
Good question - I have implemented this in the past via a strategy pattern:
When webview is hosted in a browser (which was an SPA in my case), handle tokens in a standard SPA manner - eg token renewal on an iframe / full screen login redirects
When webview is hosted in a mobile app, detect this via the user agent and call back the mobile app to do things like refresh a token or initiate a new mobile login
It is tricky but makes sense since web / mobile have very different solutions for token renewal / storage / login
It is the sort of practical real world use case where you find pretty much zero guidance online. Happy to answer any follow up questions.
Related
I am confused about the different login methods and the impacts on the user experience.
I would like to do native mobile app login on iOS, that means the user is not redirected toward the web page (or in app browser tab) to login. For example : All banking applications (Ex: N26) the login method is always the same : User enter his login / pwd and then he connects.
However, when I see the "Best practice login app for mobile" I can see they use authenticate + authorization code flow with PKCE. But using this method, my mobile app has to be redirected to the authorization server (Like when we want to connect with google).
So my questions are :
Is is possible to do native login using authorization code flow with PKCE without opening an in app browser tab ?
In terms of security, authorization code flow is better than native ? If yes, why all banking mobile applications are not using it ?
if the authorization server is the same than the resources server, is it possible to not have this redirection for the login ?
For now, my server use OpenID, tomorrow maybe OpenIDConnect.
Thank you for your answer :D.
Context
N26 as well as most banking apps do not support Single-Sign-On (SSO).
Auth code flow + PKCE is a way of securely having your user login with SSO, usually using a well known Identity Provider (IdP) as Google. Then, assuming your selected IdP follows the OIDC specs, you will be able to receive an idToken which will represent the user who just logged in and some of her details (called token claims) like her email, name, etc.
Answers
Auth code flow + PKCE is related only when you use OIDC SSO, not with native login.
In order to implement a native login you would have to be the "authority" who keeps the data required to authenticate users like email, password etc. Otherwise, Google (or any other IdP) is responsible for that. SSO provides better UX (as long as the redirect to the IdP is not poorly designed) and users prefer it since they are usually already logged in to their IdP, thus they do not have to remember and type credentials. However, the reason that lots of banks do not use SSO is that they do not trust Google. If Google gets compromised, the malicious party would be able to issue tokens that would allow them to impersonate anyone. Same for availability. If Google goes offline for some reason, users will not be able to login. I guess banks believe that they can provide better security and availability guarantees on their own.
Again, you need the redirection only when using SSO OIDC. If you are not using that, and end up using a native login no redirection will be needed. That being said, it is a good practice too keep your authentication server separate to your back end.
At my company we are developing several web applications that uses a REST API server.
First a little introduction.
The app provides the ability to manage users through the REST API and allows the users to login to the app.
Right now the REST API is for internal use only because we plan to develop more apps and communicate to the REST API as the central point of data access. We are handling the REST API authentication with a "Resource Owner Password Credentials Grant" implementation for the internal apps.
What we need is a Single-Sign on service for all the apps, we want a user to login to an app and if he/she access to another of our apps he/she will be already loged in.
We have been experimenting with the CAS protocol, with the CASino library specifically and it works great.
The problem is we don't know how to handle the flow between the apps, the REST API and the SSO service, also I don't know if there is a better choice regarding SSO services.
My questions are...
How we could handle the flow between the apps, the REST API and the
SSO service, because the REST API should be stateless it should not
communicate to the SSO service? or is there a way to communicate the
REST API to the SSO service?
Is there a better choice to implement a Single-Sign on service,
maybe OAth or OpenID and are this options suitable for REST APIs?
Thanks in advance!
Your REST API will have to talk to the SSO server to validate the Access Token, unless all the information it needs is encrypted inside the Access Token. Not sure what you mean by "flow between the apps", you should have all apps talking to a central SSO server.
When a user wants to create an account on WebApp1, the account should be created on the SSO server, either by redirecting them there or if you need a differently styled signup form for each web app, then via an AJAX call to the SSO server's REST API. I would recommend the latter as redirecting is more difficult to debug and it can make a bad user experience.
Make sure the messaging is clear, i.e. not "Sign up for a WebApp1 account", but "Sign up for a MyCompany account to get access to WebApp1".
OAuth 2.0 is very popular and people have more experience with it, so it's easier to get help or integrate with apps created by others.
The doorkeeper gem is a good server library.
OAuth 2.0 is normally used when the SSO server doesn't trust the client apps (e.g. Facebook, Twitter), but it can be implemented in such a way to skip the client authorization step (where the user is asked to approve the client app), and you can use the Resource Owner Password Credentials Grant via a REST API.
CAS is easier than OAuth. It is fairly easy to implement the basic endpoints and that way you can customize it as you wish.
I worked on a CAS-based server with a custom implementation (not sure if it was even really CAS-compliant). The authentication was done with Devise (I don't recommend Devise if you're going to customise it a lot, make your own in this case). The original flow was that the user went to the website, clicked Login/Register and then was redirected to the SSO server and after the user logged in, redirected back with a one-time ticket that the website's backend exchanged to an access token via a REST API call.
Then we added a REST API that was called from each website with AJAX. You send the username/password/captcha/etc and get back an auth token, which the site sends to its own backend. The SSO REST API can also set a cookie on its own domain, so that if the user visit another of our web apps it makes a call on pageload to check if the user is logged in. This way you're automatically logged in on every webapp without the redirect mess.
All tokens issued + the associated user info were sent to a fast Node.js app that would save them to Redis, and the app backends would call this app to validate the access tokens really fast, without putting load to the SSO Rails app.
I'm creating an app for iOS that consumes an API I've created, which requires authentication and authorization of users. I'm thinking of using OAuth to let the mobile users do this with Facebook. This is an internal API that isn't meant to be exposed to third parties.
Anyway, I'm a little confused about the abilities and limitations of OAuth consumers versus OAuth providers. Basically, I want to implement "Login with Facebook" functionality from the iOS app. It seems to me that this implies that my API should be an OAuth consumer, but the problem with this is that the login flow for a web app assumes a browser -- an NSURLConnection instance isn't going to know what to do with an HTML login page, and even if the redirect to the login page was made to work by prefixing the redirect URI with the fb:// schema, surely the login form is going to pass the authorization token back to the iOS app and not my API?
So my question is: is there a way to implement my API as an OAuth consumer? If not, and I should implement it as an OAuth provider, what does logging in with credentials from another provider like Facebook even mean?
I think things are a bit mixed up:
OAuth is to Authenticate your app against facebook. A user grants
access to his FB account to your app on behalf of him
"Login with FB" is the other way round and is not OAuth: A User
with an FB account is using this data to register AND login to your
app.
The entire flow of the # 2 can be read here.
I'm looking for some guidance on what people think are the best set of technologies to use. We are looking to create a web portal to allow customers to register/login with standard credentials or their social accounts (Google, Twitter etc).
Once they are registered and logged in to the portal they can access our different web apps which will know who they are and what permissions they have based on a token. We will also need to secure a set of web APIs using some sort of OAuth mechanism, so the user would possibly create an account on the web app and then create an application which would give them the keys they need to access the API from their own app.
We have a basic portal app using MVC 4 and DotNetOpenAuth which allows a user to create an account and login with either a username and password or their Google, Facebook account etc.
The APIs would be MVC 4 Web APIs
Ideally the whole set up needs to be as simple as possible, I've briefly looked into using Windows Azure Access Control (ACS) as a way to cut out some of the heavy lifting but its hard to tell where exactly it all fits together.
Currently we run an ADFS 2.0 server and WIF to allow web login to our apps but it doesn't seem like it would be an ideal choice when integrating the social login and for securing the web APIs
I guess it could be two quite seperate parts, once they are logged into the portal, how would we go about providing some sort of claims token to the other apps they then access to understand who the user is and what they are allowed to do. And maybe the web API authentication/authorisation is its own entity?
Thanks for your time
We ended up using the built in MVC 4 login system and also added JWT token support, when a user is logged in a JWT token containing their claims is stored as a cookie. This is then automatically passed around our sites on the same domain by the browser, when the web API is called from javascript it checks for the token in the headers sent by the browser and either validates it and returns the correct data or returns an unauthorised response.
It doesn't cover all the bases, we can't give trusted third parties access to our web services yet
I'm trying to use OAuth with .NET (DotNetOpenAuth) to send updates to a Twitter account via a web application. I understand the basic workflow of OAuth and Twitter.
Where I'm confused if is it useful in a server web application? I don't want any user interaction.
But how it seems after an application start, the request token needs to be recreated and also an access token. This involves user interaction.
What is the correct workflow for my case?
Storing the request token or access token in config file?
Or the easist way, using HTTP basic authentication?
Thanks
If I understand you correctly your application will not be interacting with Twitter on behalf of your users but will be acting as the Twitter account for your application.
In this case there are 2 main factors to consider.
1) Do you want "from API" attached to each status as will be if you use basic auth or your applications name will happen if you use OAuth.
2) Do you want to put in the extra effort to implement OAuth.
If you decide to go with OAuth you would store your apps consumer key/secret and the accounts access token in configuration just like you would store the accounts screenname/password.
Your "request token needs to be recreated" phrase suggests you might be running into the problem where every time your user visits you need to re-authorize to Twitter, and perhaps you're looking for a way to access the user's Twitter account while he's not at your web site, and how can you do this when their token isn't fresh from being re-authorized. Is that right?
If so, the user isn't supposed to have to re-authorize Twitter every time they visit your site. The token is supposed to last a long time, which would also allow your site to access their Twitter account when they are not directly interacting with your web site. The problem may be that you haven't implemented the IConsumerTokenManager interface, but are instead using the default InMemoryTokenManager, which is for sample use only, since this memory-only token manager loses tokens every time the web app is restarted. Your own implementation of this simple interface should store and read the tokens out of some persistent storage such as a database.