Discourse as SSO source of authority for Wordpress

(Kane York) #15

The URL is /session/sso_provider . Fill in the SSO_secret like normal.

(Daniel Brief) #16

Getting closer - it redirects to /login, I see a request to get /session/csrf which looks OK and then I type in name and password, hit enter and the browser does a POST to /session with my login and pw in the data and a X-CSRF-Token header with the value session/csrf returned, but I get a 500 - Internal Server Error and the dialog shows “Unknown error”. If I type in an incorrect password then /session returns a 200 with the error message “Incorrect username, email or password”. If I login with Facebook then it works.

(Daniel Brief) #17

@riking - another clue - in the log I get the following stack trace:

Started POST "/session" for at 2015-03-25 11:48:12 +0000
Processing by SessionController#create as */*
  Parameters: {"login"=>"daniel@mysite.com", "password"=>"[FILTERED]"}
Completed 500 Internal Server Error in 332ms

RuntimeError (sso_url not implemented on class, be sure to set it on instance):
  lib/single_sign_on.rb:16:in `sso_url'
  lib/single_sign_on.rb:63:in `sso_url'
  lib/single_sign_on.rb:77:in `to_url'
  app/controllers/session_controller.rb:32:in `sso_provider'
  app/controllers/session_controller.rb:250:in `login'
  app/controllers/session_controller.rb:158:in `create'
  config/initializers/08-rack-cors.rb:11:in `call'
  lib/middleware/anonymous_cache.rb:123:in `call'
  config/initializers/quiet_logger.rb:10:in `call_with_quiet_assets'
  config/initializers/silence_logger.rb:26:in `call'
  lib/middleware/request_tracker.rb:70:in `call'
  lib/scheduler/defer.rb:85:in `process_client'
  lib/middleware/unicorn_oobgc.rb:95:in `process_client'

I get that sso_url is not defined, but I’m not clear where it should be defined. I tried putting a page on my main site in the “sso url” field in the login settings, but that doesn’t seem to have any effect. Should I add it to the request that passed the nonce (&sso_url=http…? )? Some other way?

(Jens Maier) #18

Uh, this looks like a bug…

Shouldn’t that be DiscourseSingleSignOn instead of SingleSignOn in line 24?

(Sam Saffron) #19

I don’t think so … its independent to other SSO on the site. We have provider working fine for us here. I think this is happening cause @danb is not sending in a return_sso_url, which 100% required for this use case.

(Jeff Atwood) #20

If it is 100% required we need to improve our error messaging to make that clear… otherwise we’ll get future support requests for this.

(Sam Saffron) #21

Sure, we also need to properly document this feature.

(Jens Maier) #22

Then where would the sso instance get its @sso_url from? It’s never set during SingleSignOn::parse or anywhere else by the time the code calls #to_url. In fact, in this regard the whole SingleSignOn class is abstract because it contains no code that would ever set @sso_url but will inevitably fail without it being set…

(Dammit, I keep replying to the wrong posts. Meant to reply to @sam.)

(Jeff Atwood) #23

You can change who you reply to before post submission by clicking reply on the post you wanted to originally reply to while the editor is still up, and before the post is submitted. After submission, it’s just set.

(Jens Maier) #24

I know, I’m just not reading the “Replying to post #{number} by #{other user}” message anymore and end up tripping over my own mousebutton finger…

On any other forum, I’d delete the post and resubmit it, but without ninja-deletes that would cause even more noise. :frowning:

(Sam Saffron) #25

Not really abstract … see:

as long as to_url gets a base url all is good.

(Jens Maier) #26

Oooh, ok, yes, and return_sso_url is set via the request… that makes sense. :sweat_smile:

(Daniel Brief) #27

OK, added return_sso_url and added Access-Allow-Control-Origin permission for my Discourse site to my main site and login is now working :smiley:
I’m still trying to figure out:
How can my front-end know when login is completed (poll my server to see if return_sso_url has been run?)
After FB login (I assume also Google/Twitter/Github etc,) or canceling login shouldn’t return_sso_url get called? How can I tell whether login succeeded or failed?


(Sam Saffron) #28

you would need to handle that on your side, once we redirect you back then you know you are logged in.

(Daniel Brief) #29

I’m missing something here. The only redirect to my site is the ajax request to /session which gets redirected to the return_sso_url. Then there’s a request to /login which redirects to my Discourse home page. How do I tell Discourse to redirect back to my main site? Is there something return_sso_url is expected to return?
… Just realized that wouldn’t be enough since return_sso_url isn’t called in the FB or canceled login cases. So some parameter in the original request?

(Tobias Eigen) #30

@danb if you figure this out and get it working, could you write it up here as a howto topic? I’d really like to look at this route as well, in conjunction with wp-discourse.

Or perhaps this reverse-sso could be added as an optional feature in the wp-discourse plugin?

(Daniel Brief) #31

Hi Tobias,
Looks like we’re giving up on this route and going back to handling login ourselves. Our code is just getting too kludgy, although I think it’s probably possible to get it to work.
Here are some of the cases/issues we needed to handle:

  1. Add javascript to post messages to our client when the login dialog gets canceled or succeeds
  2. Login dialog appears, user clicks “cancel” - js on dialog posts a message to our client so we know he’s not logged in
  3. Login dialog appears, user logs in with username/pw - js on dialog posts a message to our client when it closes, so we know he logged in
  4. login dialog appears, he logs in with FB - js on dialog posts a message to our client, so client knows he’s logged in, but discourse didn’t call our server, so our client needs to call discourse login again so that discourse will tell
    our server the user is logged in
  5. User is logged in already - so there’s no dialog (but Discourse did call our server) - we need to check on our server if he’s logged in. But we don’t know when to check our server - maybe he wasn’t logged in and the dialog is still up? So we need to keep checking until we either get a cancel message from the dialog or our server says he’s logged in
  6. Sometimes we don’t need to login, but just to check if the user is logged in - in that case we move the login iframe offscreen so the user doesn’t see it. If the user is already logged in the server will be notified, but if not we need to wait X seconds until we can assume the user isn’t logged in…

It’s possible that I’m missing something that would make this easier - maybe since our client sometimes has to poll our server to see if login succeeded, we don’t need to bother telling the client via javascript postmessage? We still need to
notify the client when login gets canceled.
Maybe it would be easier to learn RoR and write a plugin or change the code?
Combine Discourse login with API calls?

If someone figures out something simpler I’d be interested in hearing about it (just out of curiosity, no intention to try this again).

(Tobias Eigen) #32

Thanks for posting your progress so far here - perhaps it will be of use to others who follow in your footsteps.

This is functionality that I would use immediately if it were available. Perhaps it could be an optional part of the wp-discourse plugin?

(Erlend Sogge Heggen) #33

There’s now an official how-to guide for how to do this. Not specifically for WordPress, but for any web apps like it.

(Erlend Sogge Heggen) closed #34

This topic was automatically closed 47 hours after the last reply. New replies are no longer allowed.