Weirdness with our CurrentUserProvider


(Micah Mayo) #1

Hello Discourse,

We’re having a bit of odd behavior with our custom user provider/sso. We aren’t using Discourse’s stock SSO (yes, I know, unsupported, ill-advised), but we do use bits of the internals for authentication. All requests come through a gateway proxy, and the user’s authentication info is available via the environment. For auth, we’ve created a custom user provider that more or less does the following:

  def current_user
    return if @env[USER_ID].nil?
    return @env[CURRENT_USER_KEY] if @env[CURRENT_USER_KEY].present?
    if sso_record = SingleSignOnRecord.find_by(external_id: @env[USER_ID])
      user = sso_record.user
    else
      user = create_sso_record
    end
    @env[CURRENT_USER_KEY] = user
  end

This is bootstrapped via a plugin:

Discourse.current_user_provider = ServiceGatewayCurrentUser

There’s a bit more to it, but this is a simplified version of the core mechanic: instead of having an endpoint/service to call, the request environment contains the required details, and we process them appropriately using Discourse’s SSO Internals.

This has worked well for about six months, but we’ve recently noticed an oddity in the behavior:

If the user is already logged in to our main site, and navigate to the forum, they are automatically and properly logged in.

If the user clicks on the login button in Discourse, they are directed to our login page, with the current url passed as a return_to querystring. After auth, they are returned to the forum, and do not appear logged in (and are not from the user’s perspective). The above logic is executed properly, and the user’s last_seen_at and last IP address is updated. If they do not already have an SSO record or User record on the forum, these are properly created, but they are not logged in.

Now here’s where it gets weird:

If I hard refresh, still not logged in. If I keep hard refreshing over, and over again I’ll never appear logged in. If, however, I wait about 30 seconds, and then hard refresh, I will appear logged in. I went to the network tab to see if anything stood out, and it seems that there is some correlation with the message-bus polling:

I’ve found that after logging in, we’ll see 2-3 calls to the message-bus fire, and one of them typically takes about 25 seconds to complete. Every time, if I wait for this longer call to complete, and hard refresh the site, I will be logged in. If I attempt a refresh prior to this, I will not be logged in.

My understanding of the message bus is that it primarily is used to update state on the site. New posts, replies, likes, etc… so, this is somewhat confusing to me. I do see that in 04-message-bus.rb there are some bits about the current user, but it’s not clear to me what’s going on there, and how it could relate to this behavior.

Is there some other mechanic that I am missing here? Is there any specific troubleshooting you’d recommend, or do you have any intuitions on what might be wrong.