redirect uri different for each user in OAuth 2.0 (dynamic redirect uri)? - api

We have a public API that supports OAuth 2.0 server and client flow. Per OAuth 2.0 spec, https://www.rfc-editor.org/rfc/rfc6749, each integration application will have 1 application key and users using that application will authorize that application for API access of user's data.
Things worked fine until we find application developers suggesting their users to create one application key each as users will all have their own redirect uri. Put aside the false API usage information it creates, we are seeing a big increase in application key creations that is not tolerated by our API agency.
I am wondering if we can suggest such application developers to add an extra layer for redirect between our oauth server and their users' redirect uri. So their application key will be created with a redirect uri that actually loads a page created by their application, then redirects to the user's specific redirect uri, which is inputted at the user's registration.
Hope I explain it well. I am wondering whether this exposes any more security vulnerabilities than it already has. My point is someone has to do the redirect anyways, rather than we do it with all the unnecessary extra information involved, we'd like to let our client applications take control of it.
Any suggestions/hints/clues/ideas are deeply appreciated.

Related

why auth is frequently implemented using 2 redirects

In web system, when some URL is protected, user is redirected to dedicated auth-page, and after login is (in convenient case) redirected back.
I understand that with mail.google.com and accounts.google.com the reason is huge google infrastructure, and may be different developer groups responsible for accounts and mail. And if I want to make user authenticate using Google, I become a part of it.
But in a average web app I can just do like hasAuth() ? renderProtected() : renderLoginDialog() without any redirects.
Tutorial for react router is showing example with redirects, and materials for server-side frameworks is about to do the same.
Is there any practical benefits (like security) of redirect based solution, or it's just following the trend from the giants?
This is a common implementation of Single sign-on - SSO. You basically sign in once in a dedicated server, and then you can access multiple applications which are not related without signing in again. For example, after sighing in to your google account you can access all google applications (gmail, drive, calendar ...)

Adding SSO to an existing MVC application

We have an existing MVC application which is used by multiple customers.
Currently, each customer is given a URL to our application e.g. https://myapp/mycustomername.
When they go their, they are presented with a login screen.
For some customers (not all) we want to implement SSO, and authenticate their users against their active directory, so that they never see the login screen (unless the SSO authentication fails).
Most customers won't be using this functionality.
My first question is: is this do-able? Is it possible to have an MVC application which uses both SSO and forms authentication?
If so, can anyone point me to any links explaining the process?
I've seen some good information, such as this tutorial but I can't find anything that matches my scenario.
Thanks.
This is surely a do-able task.
The steps would be
Identify the tenant name from the URL
Get the Identity Setting
If forms authentication, show them the login page
If SSO enabled, redirect to their ADFS URL
When you onboard your tenant, you will have to maintain the following metadata
TenantName
AuthenticationType : {forms / ADFS}
SSO Url
SSO Federation Metadata URL
etc
We did one such implementation that supports ADFS, Social Logins with Forms Authentication too.

What kind of application do I register for a web application that can run at an arbitrary URL?

We made a CMS that allows users to connect to Google Analytics via a connector. I'm in the process of porting this connector to OAuth2 and am wondering what kind of application I need to register.
The issue is that the CMS is installed by our clients at arbitrary URL so we don't know the complete set of redirect URLs that I would need to register a Web Server application. Google's OAuth won't let me redirect to an arbitrary URL that I pass in during the authorization request?
Would registering an installed application and then using the urn:ietf:wg:oauth:2.0:oob special redirect URI be best? Seems like this allows the user copy/paste their authorization code from the browser back into our application.
Thanks in advance!
Indeed the installed application will allow users to copy and paste and not register. This is appropriate if the clients are end users of your application, and not say, configuring it as a plugin which will then provide web services to the client's users (where such users will then be prompted via the OAuth2 consent dialog). In the latter case you probably want to ask your clients to register their own web site as web application with Google and use a configuration tool for your CMS application to set the client's redirect URLs.
Why the distinction? Because in the first case the consent action is about your relationship with your clients, but in the latter case it expresses trust between your clients and their users. For instance, you don't want your CMS application to be disabled for abuse because one of your clients has misbehaved, as it'd affect all your clients. However, if you intermediated the consent you made it difficult for Google to understand the distinction.

Single Page Application Authentication

My company is re-writing its e-commerce site as a single page application using the new Web API / SPA features in MVC 4. We're not sure about the best way how to handle authentication.
Specific questions:
How do we handle both encrypted and non-encrypted communication? Clearly, we need to use HTTPS for the login, account, and checkout AJAX, but we'd like to use HTTP for browsing the catalog in order to avoid expensive SSL handshakes that would slow the whole site down. Is this even possible for a SPA, or are we stuck with HTTPS for everything?
What sort of authentication should we use? Primarily our site will be accessed from a web browser, so cookies may be fine. But down the road, we may want to make a custom iPhone app. Is Basic Authentication, OpenId, or OAUTH preferable? If so, why?
If we go with Forms Auth and cookies, will the redirect issue be fixed for the release of MVC 4, or do I have to use the haack?
If we go with Basic Authentication, how do you do persistent sessions, so that users don't have to log in every time they go to the page again.
Which authentication methods are well supported by ASP.NET MVC 4. It'd be ideal not to have to write a lot of specialized code.
Thanks in advance
1. How do we handle both encrypted and non-encrypted communication? Are we stuck with one protocol, https, with a spa?
You are not stuck with one protocol. With a spa you can use ajax to communicate over http or https, whichever one you choose at any given time. I would use https for anytime your are sending sensitive information like a persons name or their birthdate or login credentials.
Once a user logins to your site over https then your server can set a forms authentication cookie for that user. This cookie should be an encrypted value that ties their session to the server. You must be aware that if the rest of your site is using http then you have the risk of this cookie being passed over the wire in plain text. Even though the contents of the cookie can be encrypted, using an encryption algorithm of your choosing, a malicious person can steal this cookie and jack your user's session.
This might not be a big deal to you though if they are only allowed to browse the site and create a shopping cart. Once the user is ready to checkout then you should re-authenticate the user, over https, as a sort of double check to make sure they are not a malicious user. Amazon does this.
2. What sort of authentication should we use?
Well, that's all a matter of what features do you want your site to have.
OAuth is for exposing webservices which you can allow other sites to call with delegated access. What this means is that if you have a user who wants another site (site x) to be able to access features on your site for their profile. The site x can redirect the user to an oauth endpoint on your site which will authenticate the user. Your oauth endpoint will ask the user if its okay that certain features are shared with site x and if the user agrees a token will be generated. The user passes this token to site x where site x will make server to server calls to your site. Site x will present the token in the calls so the calls to your services will be a delegated access call. OAuth is a way of provisioning other sites to make delegated access to your services. I hope i was able to explain that clearly.. I'm not always good at this.
OpenID is not a very secure way of handling authentication its more of a convenience so that users don't have to be hassled with registering an account with your site. Because OpenID is completely open you are trusting another provider to validate your users. If the third party provider's user store is compromised then your users are compromised also. It's an example of a voucher system where you are basically saying I will trust who you say you are, if you can have an OpenID provider vouch for you.
Another solution is WS-Federation. WS-Federation is if you have multiple sites and you want to have 1 authentication provider that you trust. This authentication provider can be yours and basically all your sites say if you want access to my site then you have to first be authenticated with my authentication provider. This authentication provider can live on a seperate domain and can choose any authentication mechanism it chooses. You are trusting that this auth provider will do its best job to manage your users accounts.
WS-Federation can be overkill though if you only want authentication on your site and don't have multiple sites. In that case I would just recommend doing Forms Authentication and this should be simple enough to do. There are lots of examples of how to do this and microsoft provides many solutions for how to do this. You should look into creating a custom membership provider.
Once a user has been authenticated with your site you should create a forms authentication cookie. This cookie ties the user to their session on the server. This applies to all the scenarios listed above. MVC 4 supports all the scenarios listed above also.
Thanks, and feel free to ask more questions if I wasn't clear enough.
** EDIT 12/1/2017 **
Coming back to this question years later I have learned that relying on cookies for REST based APIs is not a good idea. You don't want to create a session on your web application because it makes your app harder to scale. So, if you need authentication then use HTTPS with some form of authentication (BASIC, DIGEST, Token Based, etc..). So, your SPA client appl will set the Authorization header on every http request and then your web server app will re-authenticate every request.
The main downside of using ASP.NET's form based security is that it assumes you're want a 401 web page when your authentication fails (useless when you're doing an AJAX call) and it's really designed around doing redirects which kind breaks the whole SPA pattern. You can hack around it but it's not designed for the purpose you're using it.
This toolkit may provide an alternative to ASP.NET'as form model.
Not yet sure how mature it is ...
http://www.fluentsecurity.net
Feedback welcome.
I just started working with webapi myself so don't consider my answer authorative. I'm not a security expert though I should be. I ran into the same questions as you did and found, as you did, that there is no authorative answer though - within mvc webapi at any rate. Looking at other webapi specs may give you some inspiration.
The simplest way I came across was of course using SSL. That let's you get away with sending credentials in clear text in the header. Doesn't break rest.
My api will employ SSL all the way but I wanted to double up anyway. So I'm sending an encrypted key in the querystring for all my requests. Pretty much the way cookieless authentication works for a non api asp site, but mvc doesn't play with it so I've rolled my own solution.
On a mobile site, the user would log in, be redirected, to the app with the encrypted key encoded into the js. So he'll initially have a cookiebased auth for the site, and be responsible for it's protection, password saving etc.
Another api consumer would get a more permanent "secret" from a dev site yet to be made and use that to check out a key.
Normally mvc authentication is stateless, meaning the ticket is never invalidated server side. If you controll the client you can just ignore invalidate cookie requests if the server logs you out, and just keep on reusing the ticket. Eventuelly you might want to keep track of your tickets server side, but it's not stateless, doubt if it's restfull, and by consequence scalability taket a hit. But authentication is pretty important so...

Recommended method/authentication engine to secure an API

Hello and thanks for looking.
Background
I am designing an application that will host certain pieces of information/data for third-party websites via an API and must be accessed via authenticated requests.
Is OAuth the way to go about this or is there something better out there? I will not know the domains of the third-party sites up front so I can not rely on host-headers (which can be spoofed anyway).
Requests to the API will most likely originate in jQuery or regular JavaScript on the client side.
Question
What is the best way to ensure that third-party websites requesting data from my API are who they say they are, and are allowed to access the information they are requesting?
Many thanks!
Matt
OAuth, particularly OAuth 2 (which isn't yet finalized), will likely work well for you. But since the web requests are coming from the browser rather than the web server hosting these web sites, each individual browser will have to be authorized rather than each domain.
So let's step back and ask this question:
Is the data your API will be exposing unique per individual user or unique per web site domain? Or in other words, are you as the API owner going to contractually authorize domains to access your data, or will individual users have data accessible via your API, and those users need to authorize these other domains to access to their own data on your service?
If you're authorizing domains (and not users) then the browser simply cannot be the initiator of these authorized requests to your API. This is because the web server on those domains would have to issue their secret key to the client, at which point they've lost control of it and anyone can make these authorized calls -- not just the domains you've intended to authorize. This is the "you can't trust the client" principle in security.
If you're authorizing users, then each user who visits one of these 3rd party sites will have to go through a one-time setup where the web site redirects their browser to your service to log in and say "yes, [3rd party site] can access my data", after which they're redirected back to that site. After that, any time they visit that site, the site can download a secret key that's unique to that user and can be used from javascript on the client to make these authorized API calls.