Skip to content

Add OpenID Connect support#693

Merged
manno merged 3 commits intofrab:masterfrom
emirisman:master
Oct 19, 2021
Merged

Add OpenID Connect support#693
manno merged 3 commits intofrab:masterfrom
emirisman:master

Conversation

@emirisman
Copy link
Contributor

Adds generic OpenID Connect support for any system supporting it, e.g. Keycloak

@elad-eyal
Copy link
Collaborator

Hi @emirisman

  1. If I understand correctly what OPENID_CONNECT_REDIRECT_URI is, then there's no reason for the user to set it as an environment variable. You should be able to build it based on the environement variables FRAB_HOST, FRAB_PORT, FRAB_PROTOCOL, and one of the url_for methods (maybe this)

  2. Take a look at 42a9d18 . I created a test which uses a free LDAP server to verify everything's working OK. (I did it after LDAP got broken of course). Is there a free ominauth connect server we can similiary use for testing? I think it would be great. Some goolging led me to this and also this . Perhaps one of these can be used?

  3. I think you need to add i81n here https://github.com/eladeyal-intel/frab/blob/ba077a91705a013e631b47d41be16d40cc872bf1/config/locales/en.yml#L714 otherwise the link would say "Log in with openid_connect".

  4. I think you should add NAME_FOR_OPENID_CONNECT to the environment example (and verify it works). i.e., if one uses openid_connect to connect to Keycloak, then one would set NAME_FOR_OPENID_CONNECT=Keycloak and then users are presented with "Login with Keycloak".

@elad-eyal
Copy link
Collaborator

The i18n should be "OpenID Connect provider" @emirisman

@emirisman
Copy link
Contributor Author

emirisman commented Feb 7, 2020

Hello @eladeyal-intel - thank you for your feedback! I'll look into build the redirect URI from the given environment. I have added NAME_FOR_OPENID_CONNECT, it works as intended. I will also try to implement the tests with one of the providers you have suggested.

Regarding the translation: Currently, I am receiving the following message upon login:
Successfully authenticated from translation missing: en.devise.links.openid_connect account.

I've tried adding the following line which did not work (causes a 500 error upon login):

en:
  (...)
  devise:  
    (...)
    links:
    (...)
      openid_connect: "%{provider}"

I am expecting "%{provider}" to work since sign_in_with is defined as Sign in with %{provider} which works as expected with NAME_FOR_OPENID_CONNECT environment variable. Is there a reason why %{provider} would work in sign_in_with but not in openid_connect ?

@emirisman
Copy link
Contributor Author

@eladeyal-intel I ended up using this url_for method to build the redirect URI which seems to be working also in absence of the FRAB_PORT environment variable

@elad-eyal
Copy link
Collaborator

elad-eyal commented Feb 8, 2020

@emirisman - the %{provider} is used within devise.links.sign_in_with. You want to provide i18n to the provider variable. So you would not be defining it using %{provider}. All you need to do is set devise.links.openid_connect to OpenID Connect provider (in config/locales/*.yml) . So this will make the default "sign in" proposal to be: "Sign in with OpenID Connect provider" (instead of "Sign in with openid_connect"). In production, admin will use the env variable NAME_FOR_OPENID_CONNECT to configure this link for whatever works for him. It would override the default i18n.

@elad-eyal
Copy link
Collaborator

elad-eyal commented Feb 9, 2020

I created a free okta account with a single user for tests. I can login to it using @emirisman
code; but I was not (yet) able to integrate that into a working standalone test.

NAME_FOR_OPENID_CONNECT=dev-853138.okta.com
OPENID_CONNECT_ISSUER=https://dev-853138.okta.com
OPENID_CONNECT_CLIENT_ID=0oa24wqfphhAYjlLU4x6
OPENID_CONNECT_CLIENT_SECRET=EHJItTDlsB84CflxcYb59sHxjIO6iRimO6DcauHo

LOGIN='[email protected]'
PASSWORD='Frab2020'

@emirisman
Copy link
Contributor Author

@eladeyal-intel the test I've created fails with following:

OpenIDConnectTest#test_can_sign_up_and_sign_in_with_openid_connect:

ActionController::RoutingError: Specified conference not found

    app/controllers/application_controller.rb:112:in `conference_from_params'

    app/controllers/application_controller.rb:42:in `load_conference'

    test/features/openid_connect_test.rb:17:in `connect_with_openid_connect'

    test/features/openid_connect_test.rb:34:in `block in <class:OpenIDConnectTest>'

The request seems to be initiated though: [2020-02-09T20:10:14.907217 #18560] INFO -- omniauth: (openid_connect) Request phase initiated.

Your LDAP test does not seem to have a setup phase yet it proceeds without such errors - do you have an idea?

@elad-eyal
Copy link
Collaborator

elad-eyal commented Feb 9, 2020

I have an idea.

the capybara default driver (:rack_test) does not support running against a remote server. You will see in log/test.log a GET to /auth which should go to a remote site.

If you add js: true to the test definition# then it will use phantomjs instead of rack_test and phantomjs is able to visit other sites.

https://github.com/teamcapybara/capybara/blob/master/README.md#calling-remote-servers

@elad-eyal
Copy link
Collaborator

@emirisman you can run the test locally in your pc

rails test test/features/openid_connect_test.rb

@emirisman
Copy link
Contributor Author

@eladeyal-intel I am trying to run the test with Poltergeist and did manage to actually get to the Okta login but I am receiving the following error:
UNSUPPORTED_BROWSER_ERROR: There was an error sending the request - have you enabled CORS?

Looks like we have to adjust some settings in Okta: https://developer.okta.com/docs/guides/enable-cors/overview/

@elad-eyal
Copy link
Collaborator

@emirisman pls try again. I added some CORSs. If it still fails - I think I need to know the server that poltergeist is pretending to be. Perhaps you can set it to frab.test. You can push your code and I'll try to debug it from both views.

@elad-eyal
Copy link
Collaborator

I cannot replicate this (nor make it work) on my PC.

try setting the poltergeist option host to https://frab.test or `http://frab.test

@emirisman
Copy link
Contributor Author

Still does not work.
@eladeyal-intel I think I found the problem though: we need to add the callback URI (e.g. http://127.0.0.1:41135/users/auth/openid_connect/callback) in Okta. The problem is that the port that is used in tests changes every time - we would either need to wildcard the port (would probably not work?) or pin the Capybara port to a fixed one?

@elad-eyal
Copy link
Collaborator

elad-eyal commented Feb 14, 2020

@emirisman
I was not able to add a wildcard at the okta control panel

I thought setting the poltergeist option host to https://frab.test would help in this regard.

image

@emirisman
Copy link
Contributor Author

@eladeyal-intel It looks like the problem is Okta's automatic bot detection:
I currently have a test that actually makes it to the callback phase (yet still fails due to some configuration error):

# Running:

QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
I, [2020-02-16T00:42:16.343926 #2816]  INFO -- omniauth: (openid_connect) Request phase initiated.
Unrecognized Content-Security-Policy directive 'report-to'.

Unrecognized Content-Security-Policy directive 'report-to'.

Unrecognized Content-Security-Policy directive 'report-to'.

Unrecognized Content-Security-Policy directive 'report-to'.

Unrecognized Content-Security-Policy directive 'report-to'.

Unrecognized Content-Security-Policy directive 'report-to'.

Unrecognized Content-Security-Policy directive 'report-to'.

Unrecognized Content-Security-Policy directive 'report-to'.

I, [2020-02-16T00:42:28.719436 #2816]  INFO -- omniauth: (openid_connect) Callback phase initiated.
E, [2020-02-16T00:42:28.720346 #2816] ERROR -- omniauth: (openid_connect) Authentication failure! invalid_credentials: OmniAuth::Strategies::OpenIDConnect::CallbackError, Invalid state parameter
F

Failure:
OpenIDConnectTest#test_0001_can sign up and sign in with openid connect [/frab/test/features/openid_connect_test.rb:26]:
Expected to find text "Successfully authenticated" in "frab - home Log-in Sign Up × Authentication failed. List of conferences Current Conferences Past Conferences There is not a single conference yet. frab is a conference planning and management system. It helps to collect submissions, manage talks and speakers and create a schedule. The users manual is maintained in the wiki. The source code is hosted on Github.".

bin/rails test test/features/openid_connect_test.rb:34



Fabulous run in 13.957891s, 0.0716 runs/s, 0.1433 assertions/s.
1 runs, 2 assertions, 1 failures, 0 errors, 0 skips

However if I run the same test again it does not continue to the callback phase and simply fails at the login page

@elad-eyal
Copy link
Collaborator

elad-eyal commented Feb 16, 2020

I'm not sure this is the cause of the problem.
maybe we can learn from https://github.com/okta/okta-auth-js/tree/master/test/e2e
can you rebase and push the latest version?

@emirisman emirisman force-pushed the master branch 2 times, most recently from a0558c0 to 46c42ac Compare February 16, 2020 10:43
@emirisman
Copy link
Contributor Author

@eladeyal-intel I rebased and pushed my changes - I can locally run the current HEAD such that it makes it to the callback phase every time

@elad-eyal
Copy link
Collaborator

I can't get this to work in CI. Maybe it is anti-bot stuff. OpenID Connect integration does work for me (without CI). Maybe @emirisman should remove the failing CI, squelnch all the commits to a single commit, and wait for repository devs to decide if they want to import it.

@emirisman
Copy link
Contributor Author

I can also confirm that the OpenID Connect support works for me. @eladeyal-intel I will move the test commits to another branch and start a separate PR for it - the integration itself already works and IMHO can be merged

@emirisman
Copy link
Contributor Author

I have squashed to commits and will move the tests to a separate branch

@emirisman emirisman requested a review from erdgeist February 18, 2020 11:50
@emirisman
Copy link
Contributor Author

This might also close #20

@elad-eyal
Copy link
Collaborator

@elad-eyal
Copy link
Collaborator

Hi @emirisman

In the file app/controllers/users/omniauth_callbacks_controller.rb line 12
replace

except(:extra) 

to

except(:extra, :credentials)

In some setup I've seen this overflowing the session store.

@emirisman
Copy link
Contributor Author

Hello @eladeyal-intel - I made the change to omniauth_callbacks_controller.rb. For testing I'll look into the example you've posted 👍

@elad-eyal
Copy link
Collaborator

I was not able to add automated tests for this. I have to setup for testing this.

@saerdnaer saerdnaer requested a review from manno May 2, 2021 23:24
Copy link
Contributor

@saerdnaer saerdnaer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@manno manno merged commit 7c9f73b into frab:master Oct 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants