Automatic authentication from many different URIs


(Barry van Oudtshoorn) #1

In brief: I want users to come from one of our ~500 distinct application instances into a Discourse instance and be automatically authenticated.


We have a mixture of on-premise and cloud-hosted instances of our app. I’m keen on setting up a Discourse forum so that all users of our software can jump in and discuss things, and, to lower the barrier to entry and reduce friction, I want them to be able to do so without having to set up an account or reauthenticate.

I know that I can set up SSO for Discourse, but, understandably, there can only be one endpoint for this per Discourse instance. As we have around 500 instances of our software running – each with its own URL, and its own internal authentication, what I need is some way of passing through a trusted authentication token to Discourse such that the user is automatically authenticated. My thinking is that we’d have a key installed on all of our application servers which is used to sign the request, and Discourse will then trust this.

My understanding is that this would introduce a security issue, in that if someone were to obtain this key, they could then log in as any user in the Discourse instance. I’m not sure if there’s a way around this.

Is there a best-practice for this? Has anyone else done something similar? If so, how did you solve it?


(Matt Palmer) #2

Your suggested approach would work well enough, although as you say, it’s a security risk (especially having presumably the same key in so many places, with presumably varying degrees of administrative competence). You’d also have to write a custom plugin for Discourse to implement such a scheme, which may or may not be something you want to delve into.

Another option, which isn’t necessarily any “safer” but does allow you to use a stock Discourse instance, would be to implement an oauth2 provider external to Discourse, which itself knew all about whatever custom auth protocol you cooked up. This would remove the need to muck with the Discourse internals, and might give you more flexibility in what you could do, auth-wise. For instance, you might be able to have instances of your app “register” itself with your auth service, and negotiate some sort of per-instance unique shared key, to prevent the need to have one shared key globally. Once you’ve got all the instances registered, you can start doing callback-based verification, too.

One thing to bear in mind if you do this is username collisions. I can imagine two users named “john” on different instances of your app, causing Confusion and Delay when they both try to use your Discourse instance…


(Felix Freiberger) #3

A similar approach is to develop a small web service that acts as a SSO endpoint for Discourse, and handles authentication as you explained. I’d prefer SSO if your are certain that only users of your app should use Discourse, and prefer oauth2 if you also want to support different ways to log in (e.g. for potential customers).


(Barry van Oudtshoorn) #4

Thanks Matt; I appreciate the quick response!

I’ll have a look at building out a plugin to handle the token-based authentication – it’s not as robust as building a central authentication server, but it has the benefit of being a whole lot simpler and therefore a whole lot quicker to build and get into production. :slight_smile:

Down the track, we’ll look at a central authentication server; we’ll likely need something like this for other work in the future, so it’s probably not a bad idea to avoid painting ourselves into a corner.

We would resolve username collisions by making the username the email address – if someone owns the same email address at two instances, they’re the same person. (We don’t do email address ownership verification, but for our particular use-case, that’s less of an issue; we’re deployed into schools, and staff and student email addresses tend to all be within the same domain and thus “owned” by the school.)


(Barry van Oudtshoorn) #5

That’s not a bad idea, Felix. I’m not sure if I necessarily want to close the door on allowing potential customers in to the forum, though – it could be a really valuable part of pre-sales and pre-implementation. So for now I’ll look to build the token-based authenticator such that it’s seamless when you’re coming from the software itself, but still allow other people to login directly.