I'm writing a Windows 8 Metro app (client-server) and would like to allow my users to login using their existing accounts (Windows Live, Google, Facebook, Yahoo, ...).
Currently I'm using OAuth 2.0 on the client to retrieve a code which can be used on the server side to fetch an access token from the provider and to read basic information about the account.
I recently read about OpenID, but it seems, that there are no implementations for desktop applications. Also, Windows Live doesn't seem to support OpenID.
So my questions are:
Is it a bad practice to use OAuth to delegate authentication only?
Should I implement my own OAuth provider in ASP.NET for API access of my client and delegate the authentication task to OpenID-Providers in the OAuth web forms?
OAuth is overkill if you're only wanting to authenticate a user (after all, you're asking your customer if you can act on their behalf with the service used to authenticate with); Or, as a more concrete example, if you were delegating authentication to Twitter, you could also read all their contacts and lots of other stuff that you don't need - that might be enough to put some customers off using your app, and giving it a bad review in the store.
It's slightly different when the customer already has a relationship with the web service, and understands that your application is a client of it.
Related
I've been reading a lot lately about WEB API authentication mechanisms and I'm a little bit confused regarding how to implement my Web API authentication mechanism, I'm thinking on using Token based authentication but I'm not sure if it is the right choice.
Basically my Web API will manage all the operations needed and it will store the users of my website as well the API users(in case they have to be separated).
I want to support the following
User can register on my website and apps using their G+ or Facebook account or an already created username from my service, as well they will be to login using their social account.
If the user is not logged in they won't be able to post Items but they will be able to see the Items, think something like Craiglist.
Let's say the user is a developer and they want to post the items through some software they created instead of going through the website and posting one item at a time, how do I allow this?
Now, my questions are: 1) When a user registers on my website, do I have to create a (public key/ secret key) for it subsequent access token , so I can use my API from the website as the user checking if they have access to certain endpoints?
2) Do I have to assign a (public key / secret key) for my website so I can consume the API when the user is not logged in?
3) The same as above for mobile apps
4) How do I allow users to (sign up / sign in) using G+ or Facebook?, if they log in using any social network how am I going to secure my api?
Please, any answer will be really appreciated.
Thanks
For ASP.NET Web API 2, I would recommend you to use the default Owin OAuth2 authentication. It's a standard form of authentication well documented enough. If you do not have enough knowledge about OAuth2, read the RFC.
With Web API 2, ASP.NET moved to a new security model, called ASP.NET Identity. There is this really good video that explains the basics. The point is that starts from scratch, ignoring traditional basic, forms, or windows authentication.
A lot of learning material is on the ASP.NET website.
For local, individual accounts (questions #1, #2, and #3), look through this tutorial - here basically your own server will act as an OAuth authorization server, and the Owin OAuth2 implementation will take care of generating access token and authenticating them. Since you'll be using the OAuth 2 standard, it will be basically the same for mobile as well.
For external accounts (question #4), read through this tutorial. There are official libraries for third-party authentication for the major providers:
Microsoft.Owin.Security.Facebook
Microsoft.Owin.Security.Google
Microsoft.Owin.Security.Twitter
Microsoft.Owin.Security.MicrosoftAccount
It would helpful to also learn more and understand the new OWIN specification, that describes how web apps need to created for the .NET framework, and the Katana project (Microsoft's OWIN implementation).
Follow this tutorial for most of your requirements http://bitoftech.net/2015/01/21/asp-net-identity-2-with-asp-net-web-api-2-accounts-management/ Logging in via facebook/G+ MVC already has the helpers commented out. You would get the credentials by setting up key's via the third party apps and then store the identity.
Updated based on questions from #user18044 below
If a user is authenticated in two different web applications via 2 different SAML-based identity providers, and one of the applications needs to request data from a web API exposed by the other application, would it be possible to call the web API methods securely by virtue of the user's current authenticated status in both applications without separately securing the API methods via an API level authentication protocol such as OAUTH? Note that both applications are owned and operated by my company and share the same 2nd level domains and user base, even though the identity servers are different (one is legacy).
Some further information: Application A is a portal application that is going to host widgets using data supplied from Application B. Application A will only communicate with application B via a web API exposed by application B. Currently application B does not expose a web API (except internally to the application itself). This is new functionality that will need to be added to application B. Application A will use Okta as its SSO. Our lead architect's proposal is to continue to use a custom legacy IDP server that we developed internally based around using the dk.nita.saml20 DLL. They are both SAML based I believe, but I don't think they could share the same identity token without some retrofitting. But this is hitting the limits of my knowledge on the topic of authentication. :) I think our architect's plan was to have the user authenticate separately using the two different identity providers and then only secure the web API using CORS, his reasoning being that since the user is already known and authenticated to use application B, that there wouldn't be any security implications in allowing application A to call application B's web api methods, as the user should be authenticated in application B. This seems quirky to me, in that I can imagine a lot of browser redirects happening that might not be transparent to the user, but other than that, I'm just trying to figure out where the security holes might lie, because it feels to me that there would be some.
I know that this approach would not be considered a best practice, however with that being said, I really want to understand why not. Are there security implications? Would it even work? And if so, are there any "gotchas" or things to consider during implementation?
To reiterate, our lead architect is proposing this solution, and it is failing my gut check, but I don't know enough on the topic to be able to justify my position or else to feel comfortable enough to accept his. Hoping some security experts out there could enlighten me.
It's hard to answer without knowing more on how your current applications and APIs are secured exactly. Do the web application and its API have the same relying party identifier (i.e. can the same token be used to authenticate against both)?
If both web applications use the WS-Federation protocol to authenticate users, then most likely the SAML token will be stored in cookies that were set when the identity provider posted the token back to the application.
You do not have access to these cookies from JavaScript. If the web API that belongs to application B uses the same cookie based authentication mechanism, you could use this provided you allow for cross origin resource sharing.
If your web API uses something like a bearer token authentication scheme (like OAuth) or has a different relying party id in the STS, this would obviously not work.
I think the reason this fails your gut check is because you are basically accessing the web API in a way a cross-site request forgery attack would do it.
A problem I see with this approach is that if the user is not authenticated with the other web application, then the call to your API will also fail.
I agree with user18044 as far as it being based on a cross-site request forgery attack and the security between applications. Is it true that if User X has access to App A, that they will have access to App B and vice versa? If that is not the case, then each application will need to be authenticated separately...and it won't be a SSO. I found these links that might be helpful in your situation.
https://stackoverflow.com/questions/5583460/how-to-implement-secure-single-sign-on-across-various-web-apps
https://developer.salesforce.com/page/Implementing_Single_Sign-On_Across_Multiple_Organizations
I am working on an internal authentication system for users of a set of of RESTful web applications. Our intention is that a user should be able to sign-on once via a web form and have appropriate access to all these RESTful applications in our domain, which may be distributed in a private cloud across many servers. (I understand already that having a single authenticated session is not aligned with a pure RESTful approach, but this is a usability requirement.)
The applications themselves will be written in a variety of programming languages so a language-neutral approach is required. It was suggested to me that we might use OpenID or OAuth or a similar framework to handle the authentication but my understanding is that these are intended for third-party services and not the first-party services that would share data on our internal system. In this case, we might have a central provider service with all the other applications treated as third parties (or relying parties).
Questions:
Are OpenID/OAuth suitable for authentication among first-party services?
If so, how would one be advised to set up authentication for this use case?
Wouldn't a user have to grant individual permission to each first-party server that they wanted to use, just as they would need to grant individual permission to any third-party server? I think this would violate the requirement of having a single sign-on for accessing all the first-party services.
Are there good examples of sites supporting this first-party use case?
What would be a good alternative framework for this first-party use case?
You do not need OAuth for SSO services.
The primary use/advantage of OAuth is, as you know already, granting access to a 3rd party app to access/use your resource in a controlled manner.
Rather than having an authentication/authorization server that you would need for OAuth, why not use a single log in service across all your APIs. An OAuth access token is totally different from what you need.
As far as I understand, what you can have is something like OAuth in a way that your server vends out tokens to the app. (I'm assuming that it's a totally internal system, so tokens cannot be misused).
So basically what I'm proposing is:
When an app tries to access the first API it's redirected to a web-form.
The user enters credentials and is taken to the DB for verification. Let there be a service that generates a token for the user/app
Next API access request would be made with that token - the token uniquely identifies the app
Depending on the level of security you need you can sign some text using HMAC and send it as token, or if its totally internal just generate a unique identifier for the app/user and send it to other API
On receiving the token, each service first calls the main server with the token and internally fetches the corresponding customer/user ID and performs the required function.
In short separate the login + token generation + token verification into a different module. All APIs should use this module for login/token verification.
What I have proposed here works like OAuth but all security aspects have been stripped down since you want to use it in a private cloud.
Oauth supports multiple different kinds of flows. You can use the client crendentials flow from Oauth 2.0 to avoid asking the user to grant permission for every app (this is intended for the cases where you control both the server and the app or where you want to preauthorize certain apps). This post does a good job explaining everything: http://tatiyants.com/using-oauth-to-protect-internal-rest-api/
We are designing a web service for an application that takes OpenID as an authentication option. The question came up how do we enable API access for this user at a later time?
For clarity here is an example:
1) user A visits the site and registers using Yahoo (or other) OpenID
2) at a later time we'd like to enable API access to backend synchronization apps that act on behalf of this user.
3) giving an app a key that can access all accounts everywhere is not an option for security reasons
What are examples of using patterns like that?
Standard OpenID requires a browser because it depends on being able to load a page from a foreign site to complete the signin process. Therefore it's not appropriate for server-to-server API use.
It is more common to use OAuth as an authentication mechanism for server-to-server APIs. While standard OAuth also requires a browser and a user-interactive flow to grant access to a new application, it results in a token that can then be used by the application to act on behalf of the user for user-unattended requests.
Facebook is possibly the most high-profile user of OAuth 2 for APIs, and its Login Architecture document describes the various login flows they support at a high level. The one titled "Server-side Login" is the conventional OAuth flow, while others are different approaches that support different use-cases like mobile app sign-in and access from client-side JavaScript embedded on other sites.
I am currently developing a web application that is right now comprised of a front end which displays and interacts with the data using a REST API we have written. The only thing that will ever use the API is our front end website, and at some point a mobile app that we will develop.
I have done a lot of reading about how OAuth is the ideal mechanism for securing an API and at this point I am starting to have a good understanding of how it works.
My question is -- since I am never granting access to my API to a third-party client, is OAuth really necessary? Is there any reason it is advantageous? Furthermore, because the back end is simply the API, there is no gateway for a user to authenticate from (like if you were writing an app using the Twitter API, when a user authenticates they would be directed to the Twitter page to grant to access then redirected back to the client).
I am not really sure which direction to go in. It seems like there must be some approach halfway between http authentication and OAuth that would be appropriate for this situation but I'm just not getting it.
From my point of view, one of the scenarios that favor OAuth over other options is to work with untrusted clients, no matter if these are developed by you or a third party.
What's an untrusted client? Think from the point of who handles the credentials that grant access to your API.
For example, your web application could interact with your API in two falvors:
Your web app server side talks to your API. Your web app server is a trusted client because the credentials to access your API can only be access by whom have access to the server...You and your team. You could authenticate your web app server with a client_id and a client_secret.
You may want to make calls directly to your API from your Web app client, which runs on the end user's browser using JavaScript. The end user's browser is an untrusted client. If you were to deliver the credentials to your API down to the browser, anyone could check the JavaScript code and steal your credentials.
A third party Native App is also untrusted. A malicious developer that uses your API could save the credentials of and end user of your platform.
Your Native App is a trusted client and could manage the authentication with a simple username , password and a client id identifying your App.
How can OAuth help? OAuth Authorization code and Implicit grants can help you with this issue. These flows only work with clients that support a redirect, like a browser. And let you authenticate an untrusted client and a user against your Authorization Server to gain access to your Resource Server, your API, without exposing the credentials. Take a look at the RFC to see how it is done.
The good thing of OAuth is that it not only supports these redirect based authentication flows, but it also supports client credentials grant and user credentials grant. So an OAuth Authorization Server would cover all cases.
OAuth 2.0 originally seems like a PITA if you think about having to build a lot of it yourself, but most languages have some really solid OAuth 2.0 setups which you can just bolt in with varying amounts of fiddling. If you're using a framework like Laravel or RoR then it's barely any work.
PHP: http://oauth2.thephpleague.com/
Ruby (Rails or Grape): https://github.com/doorkeeper-gem/doorkeeper
If you don't want to redirect users as suggested in your post then ignore other comments and answers that talk about two legged flows. You can use the client_credentials grant type to have apps just provide their client id and secret in return for an access token, which is nice and easy.
I would ask how private are we talking, because if the only systems talking to it are within the backend and have no interaction with the outside world you could probably leave it wide open and just rely on the network to keep it safe (VPN/Firewall).
But if it's private in the sense of "our iPhone app uses it" then you definitely want to go with OAuth 2.0, or something like it.
2 legged OAuth is probably what you want to use. It's basically hashing a shared key, but you have the advantage of not having to write the code yourself.
Here's a related question: Two-legged OAuth - looking for information
You should use Oauth for mobile device to API layer communication.
However, there is no benefit of Oauth in this web UI layer to middle-layer access (machine to machine).
On the other hand there are some potential issues
Managing the access token expiry becomes a pain. Consider that your UI has to cache the access token across multiple nodes in a cluster. Refresh it when expired, and the fact that UI layer is negotiating security with backend will just take extra time once in a while.
In two legged Oauth (OAuth Client Credential as in v2.0) does not support any encryption. So you still need to send key and secret both to the server for getting an access token.
Backend has to implement issuing access token, refresh token, validating access token etc, without any significant benefit