OpenId Connect Plugin with AWS Cognito

Hi. Brand new to Discourse. I have an app running on AWS, which uses Cognito for authentication. I want to link this app to my new Discourse hosted forum. I’ve got a good start, but I’m hoping somebody can provide guidance on the final steps to do this.

The goal is to make the login experience seamless between my app and discourse forum. So:

  • If a user is logged into my app, when they go to the Discourse forum Discourse recognizes this, and does not require a re-log in.

  • Similarly, if a user first goes to the Discourse forum and is not logged in, Discourse will redirect them to my app’s login page (or a hosted login ui if need be).

The OpenId Connect Authentication Plugin seems like its made well for this. I have signed up for a Business Plan with Discourse to be sure I can use this plugin.

I have gone through the instructions provided by @david and have done what I believe is the setup on the Cognito side:

  1. From Cognito, I have gotten the “openid connect discovery document”, and “openidconnect client id”.

  2. On my Discourse settings, under openId_Connect, I have added these in and saved them.

  3. I have checked “enable openID connect authentication”, and under openid connect authorize scope, entered “openid email”. I have saved these settings.

According to the plugin description, this should be good to go, correct?

Well, when I log into my app, and then go to my forum, nothing happens. It just shows the normal home page with “signup” and “login” buttons present. I am hoping that it auto-logs me in after checking with Cognito, but it does not. What else do I need to do?

Additionally, if a user were coming to the forum site fresh (without every logging into my app), they should not see the Discourse signup and login buttons–rather, they should see a button that they would click that would redirect them to my app’s login. How do I add this?

And finally, users subscribe to my app and pay to use premium features. This is saved as custom attributes for the user in Cognito (there is a custom attribute that says Subscribed or not). Only Subscribed users should be able to post to the forum. So, when Discourse checks with Cognito to get the user’s information, it needs to check the user’s custom attribute, and only if the user is subscribed give them the ability to post. How do I do this?

Being so new to Discourse, I would greatly appreciate any information that anyone has about any of these questions. Thanks!

Hi @JQ331 :wave:

Auto-login is only supported if your site is private (has the login_required site setting enabled).

That should be how it works already. Make sure you disable all other login methods, including ‘local logins’.

Unfortunately this is not possible using the OIDC plugin.

1 Like

@david , thanks very much for your reply. This is helpful.

Where is this “login_required” site setting? By “private”, do you mean users can only view the site content if they are logged in? Obviously that’s not what I want here. I want it just to be where you have to be logged in to post, and the only way you log in is through my separate app.

I assume you mean in settings -> login -> enable local logins (uncheck this). So, I have unckecked all the local login stuff. But what should I check here? For example, if I am using the plugin to link the my separate app for login, is that separate app an “sso” or “oauth2”? (Wondering for example if I should select “sso overrides email” or “oauth2 overrides email”?

On only paying users able to post:

This is a fundamental requirement, so maybe I’ll have to be creative. Is there another option other than the SSO plugin? If not, I could still see this working if one of these is possible:

  1. Discourse has different level of user permissions. So that I could make it that a user could be logged in, but not have the permission to actually post or reply to posts. In this case, I would need to set the user’s permission level based on information that Discourse gets from cognito (whether subscribed or not).

  2. If that doesn’t work, does Discourse have a working stripe plugin, that allows users to be logged in, but only able to post if they are paid up through the stripe system?

  3. If neither of these work–for instance, if Discourse does NOT have the ability to distinguish among user privilege levels that I can set–then it sounds like I would need to make it so that a user is either logged in or not, and only logged in users can post. Does that sound right?

If that is the case, then I’d have to figure out on my own app end how to tell discourse to only log in the user to discourse if they are paid up in my app.

Thanks.

In that case, auto-login is not currently supported. Users will have to click the log-in button

Ok, so now the log-in button should link directly to your identity provider. Is that working?

Yes, you could set all your categories so that “everyone” can read. But only users in a certain group can create/reply to topics. If you want to automate it, you could use the API to add/remove people from a group.

2 Likes

Cool–seems like I’m pretty close. Just to confirm:

I want the following to be the case:

  1. Everyone can read site content (logged in or not)
  2. Only logged in users can post.
  3. If you are logged in to my app, when you go to Discourse, it talks to cognito, and automatically logs you in, enabling you to post.

Are you saying that (3) is not possible? You’re saying that, for some reason, auto-login ONLY happens if the site content is hidden to the public?


Sounds like this is what I want to do. From your saying “use the API”, I assume you’re saying something like:

  1. User tries to log in to my forum.
  2. They get redirected to log in to my app.
  3. When they log in to my app, my app checks whether they are paid up or not. If they are paid, my app makes a call to the Discourse API to add that person to the “group” that is able to post and reply.

Is that what you mean? If so, is there a go-to doc for understanding how to add people to groups through the API?

Thanks, this is really moving me forward.

I think maybe we have different definitions of ‘auto-login’.

Discourse can connect to an OIDC provider for login. This process is started when the user clicks the ‘login’ button on the forum. This always works, regardless of the configuration.

If a site requires login (i.e. the login required setting is enabled) then the user is redirected straight to the OIDC login screen without needing to click the button.

Yes, that’s what I was thinking. Here is some documentation on that API endpoint.

1 Like

Cool. Thanks! I’ll take a look at that API doc. Sounds like that is very promising.

On the “auto-login” thing–seems you mean “auto-login = automatically send the user to a login screen”. So sounds like what you are saying is that when a user goes to my discourse forum, there are two options:
Option 1. The site “automatically” sends them to the separate app login. This would happen whether or not the user is logged into my app already. (this is what you are describing as “auto-login”, and you are saying this happens if you set "login_required).

Option 2. The site does not do any automatic redirection. Rather, there is the basic login button on the page. If a user clicks that button, or tries to post, the forum will redirect them to my app’s login.

I was hoping for Option 3: If a user is logged in to my app, when they go to my discourse forum, my discourse forum checks with Cognito as to whether the user is logged in or not. If they are logged into Cognito, then Discourse logs them in to the Forum, without having the user separately log in again.

I’m new to OpenID stuff, but I definitely had thought this was possible, because if a user has to log in separately to the app and also the forum when they switch between the two, that is not a seamless experience.

Isn’t there a way for the Discourse forum to check with Cognito, and adjust the user’s login status without having the user have to go through a separate login process?

BTW, I’m assuming that integrating discourse directly into my app wouldn’t help. I’d do it if I could, but it looks like this is only possible with iframes, and that wouldn’t help the authentication problem.

1 Like

It is technically possible in the OIDC specification, but unfortunately Discourse does not currently support it.

1 Like

Hmm. I have heard that there are two ways to do the link between Discourse and a separate auth provider like cognito: the OpenId Plugin, or using Single Sign On for discourse.

I’m not familiar at all with the Single Sign On process, but could that be a way to do what I want–avoiding having users log in twice?

Or maybe just, when they sign in to my app, sending an API call to discourse and logging them in that way?

(the doc I linked to also talks about specifying group membership–I assume that would accomplish what I want in terms of saying only PAYING users can be in the group that is allowed to post)