OAuth provider with multiple consumer keys for single app - oauth

I'm working on an appengine app which uses OAuth. Naturally, I'm dealing with multiple versions of the app simultaneously - a local version for development, a staging version and a deployment version.
To work with these, I need three separate sets of OAuth consumer keys/secrets as the callback on authentication is defined on the provider's site.
I was wondering if there are ways for providers to provide multiple keys/secrets for a given app - this would seem to make more sense than setting up a new app each time. (Of course, it requires the provider to implement this, but it seems a natural thing to implement and I haven't seen it).
More generally, what standard approaches are used to deal with this - my guess is register multiple apps and have logic in the app to determine if it's in development mode, staging or deployment. Any thoughts welcome.

I find this to be one of the most annoying parts of being an OAuth API client developer. There is no reason why providers should not allow developers to register redirection (callback) URIs for testing.
The standard approach I've seen is to allow you to whitelist one or more domains for callback / redirection. Facebook has some crazy setup where they let you "register" multiple domains by using different domains for the various links in the application profile. I did not have much luck with that. Twitter is one of the better implementation for that, letting you register multiple domains.
In OAuth 2.0 (draft 18 or newer), this topic gets much better treatment. Registration of the full URI is recommended, with the ability to register multiple callbacks and select the one you want to you dynamically at request time.
The main aspect to consider is how you want to handle permissions with a staging setup? Do you want to be able to reuse existing approvals or want to keep those separate? Also, if the API provides special client-only calls (such as client storage or management tools), do you want the stage version to share it or keep its own (so that testing will not mess up production).
At the end, providers should provide a complete development environment and that includes testing facilities for API clients. Most don't.

From an API provider's perspective your app is simply an app using the APIs. Usually there is no such thing as a "staging" API, which does not deal with live production data. Whatever it is you are testing, you are testing it on live data right?
If you are able to register several different applications with for example different callbacks then I think your problem is pretty much solved. My view is that it should be the consumer's responsibility to keep these things separated.

Related

New single page app needs to authenticate to legacy app using Shibboleth

I am creating a new React SPA. Users of a legacy app need be able to use the new app without re-authenticating. So I need to support SSO.
It's important to note that it is also required that users of other (currently unspecified) apps should also be able to use the new app without re-authenticating, so whatever approach I take needs to be sufficiently decoupled to potentially allow this.
The legacy app supports authentication via Shibboleth, the new app currently has no authentication method, but uses JWT for authorisation.
I'm wondering if anyone has any experience of such a scenario? It seems to me that I probably need to be create an OAuth2 authorisation server for the new app to talk to and I need to somehow bring Shibboleth into the mix for the authentication, maybe with the authorisation service acting as a Shibboleth Service Provider. Googling around hasn't revealed much useful info.
Is what I've described along the right lines? I know it's very high level and woolly, but I'm really not sure of the approach to take. Any advice, information or experience in this area would be gratefully received!
GOALS
It's a little bit of a subjective question, but the main goals are usually as follows:
Focus on building your UI and API security in a future facing manner
Also provide good Login Usability
Also deliver on non functional requirements such as availability / reliability
AUTHORIZATION SERVER
On the first point, the modern option is to integrate UIs and APIs with an Authorization Server - perhaps as in My Tutorial. Your architecture is then good, but the migration is not trivial.
FEDERATING TO SHIBBOLETH
The Authorization Server can then redirect to Shibboleth and talk SAML2.0 to achieve Single Sign On, as you suggest. It is a complex solution though, and may be a backwards step in some ways.
AVAILABILITY
This is usually a big concern, and most companies use a cloud provider such as Azure / AWS due to its high availability / low maintenance / low cost. Would this be a better option for you?

Using Azure AD to secure a aspnet webapi

I'm writing an application that will be the backend for a react website. The website is to be used by our customers, but we will fully control the permissions of the user. We have decided to use Azure AD to secure requests, but will also be exposing the API for end users to use directly if desired.
My understanding is in Azure AD I will have to create an application that will allow web based implicit authentication (for the react site), as well as a native application that will allow a dameon based application to authenticate to the API.
This I believe means I will have two audience ids in my application.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Sorry I'm just totally lost and the documentation is beyond confusing given how frequently this appears to change!
TLDR: Do I need two applicaitons configured in azure ad, and if so whats the best way to set permissions (claims). Also is oAuth 2 the right choice here, or should I look at open id?
Right away I gotta fix one misunderstanding.
Daemon apps usually have to be registered as Web/API, i.e. publicClient: false.
That's because a native app can't have client secrets.
Of course the daemon can't run on a user's device then.
Since that's what a native app. An app that runs on a user's device.
This I believe means I will have two audience ids in my application.
You will have two applications, at least. If you want, the back-end and React front can share one app (with implicit flow enabled). And the daemon will need another registration.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
Yes, ids are included only. If you need names, you go to Graph API to get them. But why do you need them? For display? Otherwise, you need to be using the ids to setup permissions. Names always change and then your code breaks.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Your thoughts for multi-tenant scenarios are correct. If you did want to implement these though, I made an article on it: https://joonasw.net/view/defining-permissions-and-roles-in-aad.
Why would you need to setup the roles in multiple apps though? Wouldn't they only apply in the web app?
If the native app is a daemon, there is no user.
Overall, I can see your problem. You have people from other orgs, who want access to your app, but you want to control their access rights.
Honestly, the best way might be to make the app single-tenant in some tenant which you control. Then invite the external users there as guests (there's an API for this). Then you can assign them roles by using groups or appRoles.
If I misunderstood something, drop a comment and I'll fix up my answer.
Azure AD is of course a powerful system, though I also find the OAuth aspects confusing since these aspects are very mixed up:
Standards Based OAuth 2.0 and Open Id Connect
Microsoft Vendor Specific Behaviour
ROLE RELATED ANSWERS
This is not an area I know much about - Juunas seems like a great guy to help you with this.
OAUTH STANDARDS AND AZURE
I struggled through this a while back for a tutorial based OAuth blog I'm writing. Maybe some of the stuff I learned and wrote up is useful to you.
AZURE SPA AND API CODE SAMPLE
My sample shows how to use the Implicit Flow in an SPA to log the user in via Azure AD, then how to validate received tokens in a custom API:
Code Sample
Write Up
Not sure how much of this is relevant to your use case, but I hope it helps a little on the tech side of things...

Authentication (Passport) enough for security with Node js backend server?

Is PassportJS using Facebook Authentication enough for an iOS backend with Node JS?
I have the toobusy package as well to decline requests when things get to busy (I'm guessing it would be good for DDOSes).
I'm thinking of using nginx as a reverse proxy to my Node.JS server as well.
What are some more security measures that can scale? Some advice and tips? Anything security related that I should be concerned about that PassportJS's authenticated session can't handle?
It’s a bit hard to cram in all security-related best practices in one post, but for what it’s worth, here’s my take on the issue.
Providing authentication and securing it are two separate things. PassportJS will be able to handle everything related to authentication, but it’s an entirely different thing preventing it to be fooled or overwhelmed.
One (big) reason for putting PasswordJS behind a reverse proxy (RP) is that you’ll be able to provide a first line of defense for anything related to HTTP: header/body lengths/data, allowed methods, duplicate/unwanted headers, etc.
Nginx/Apache/HAProxy all provide excellent facilities to handle these cases and on the up-side, you get a nice separation of concerns as well: let the reverse proxy handle security and let PassportJS handle authentication. Architecture-wise, it will also make more sense because you’ll be able to hide the number and infrastructure of PassportJS nodes. Basically, you want to make it appear as there is only one entry point for your clients. Scaling out will also be easier with this architecture. As always, make sure that your RP(s) keep as little state as possible, preferably none, in order to scale linearly.
In order to configure your RP properly, you need to really understand what how PassportJS’ protocols (in case you want to provide more authentication methods than just Facebook’s) work. Knowing this, you can set up your RP(s) to:
Reject any disallowed request HTTP method (TRACE, OPTION, PUT, DELETE, etc).
Reject requests/headers/payload larger than a known size.
Load-balance your PassportJS nodes.
One thing to be on the lookout for in terms of load-balancing are sticky sessions. Some authenticators store all their state in an encrypted cookie, others will be a simple session handle, which only can be understood by the node that created the session. So unless you have session sharing enabled for the latter type (if you need PassportJS resilience), you need to configure your RP to handle sticky sessions. This should be the maximum amount of state they should handle. Configured correctly, this may even work if you need to restart an RP.
As you diligently pointed out, toobusy (or equivalent) should be in place to handle throttling. In my experience, HAProxy is bit easier to work with than the other RPs with regards to throttling, but toobusy should work fine too, especially if you are already familiar with it.
Another thing that may or may not be in your control is network partitioning. Obviously, the RPs need to be accessible, but they should act as relays for your PassportJS nodes. Best practice, if possible, is to put your authentication nodes on a separate network/DMZ from your backend servers, so that they cannot be directly reached other than through the RP. If compromised, they shouldn’t be able to be used as stepping stones to the backend/internal network.
As per Passport documentation:
"support authentication using a username and password, Facebook, Twitter, and more."
It is the middleware, with which provides the feasibility to integrate multiple type of security methodologies with NodeJS.
You should consider the purpose of the application, is it only supporting Facebook Authentication or custom register/login process. If it is providing second option, then in that case, it is better not to rely on authtoken of any social networking site like Facebook/Twitter or any other.
The better option is to create your own token like JWT token, and bind it with the user from multiple platforms. It will help you in extending the scope of your project to integrate other social networking sites.
Here is the link to integrate JWT in NodeJS.
https://scotch.io/tutorials/authenticate-a-node-js-api-with-json-web-tokens
Similarly there are many other blogs and tutorials available in market to integrate JWT with NodeJS

Restrict access to web service to only allow mobile clients

I'm currently building a mobile application (iOS at first), which needs a backend web service to communicate with.
Since this service will be exposing data that I only want to be accessed by my mobile clients, I would like to restrict the access to the service.
However I'm in a bit of a doubt as to how this should be implemented. Since my app doesn't require authentication, I can't just authenticate against the service with these credentials. Somehow I need to be able to identify if the request is coming from a trusted client (i.e. my app), and this of course leads to the thought that one could just use certificates. But couldn't this certificate just be extracted from the app and hence misused?
Currently my app is based on iOS, but later on android and WP will come as well.
The web service I'm expecting to develop in nodejs, though this is not a final decision - it will however be a RESTful service.
Any advice on best practice is appreciated!
Simple answer: You cannot prevent just anybody from acecssing your web site from a non-mobile client. You can, however, make it harder.
Easy:
Send a nonstandard HTTP header
Set some unique query parameter
Send an interesting (or subtly non-interesting) User Agent string
(you can probably think of a few more)
Difficult:
Implement a challenge/response protocol to identify your client
(Ab)use HTTP as a transport for your own encrypted content
(you can probably think of a few more)
Of course anybody could extract the data, decompile your code, replay your HTTP requests, and whatnot. But at some point, being able to access a free Web application wouldn't be worth the effort that'd be required to reverse-engineer your app.
There's a more basic question here, however. What would be the harm of accessing your site with some other client? You haven't said; and without that information it's basically impossible to recommend an appropriate solution.

OAuth for multuple internal apps and main site

I have one main Asp.net MVC application, I also have a help site and quite a few internal apps (that I need to build - reporting, stats, support tickets).
Question: Can OAuth be used in this way? i.e. a user can be authenticated to use all apps (if they have access to that app)?
Ideally all or most of the other apps will be implemented in Ruby or Node.js - so I am hoping I can achieve this with OAuth.
As long as all of your apps run under the same top level domain, it should not be strictly neccessary to use OAuth or similar to obtain a shared session. Instead you could rely on a plain session cookie. You could run some kind of middleware in between your app and the user.
Only if the main app is providing a REST API that you may want to use on various client apps, where some of them run in external environments / domains, making use of OAuth may be relevant.

Resources