Hello,
I am trying to configure SAML SSO in my Tutor 11.2.3 instance.
According to Getting started with plugin development — Tutor documentation, I have installed SAML plugin, enabled it, created content file according to README on pdebruic/tutor-saml
Github page(sorry, new users can have only 2 links…), saved and restarted. Plugin is enabled:
ubuntu@openedx-dev:~$ tutor plugins list
saml==0.1.0`
Generated .key and .crt with openssl req -new -x509 -days 3652 -nodes -out saml.crt -keyout saml.key
. This is the content file, $(tutor plugins printroot)/saml.yml
:
name: saml
version: 0.1.0
patches:
common-env-features: |
"ENABLE_THIRD_PARTY_AUTH": true
openedx-lms-common-settings: |
# saml special settings
THIRD_PARTY_AUTH_BACKENDS = "third_party_auth.saml.SAMLAuthBackend"
openedx-auth: |
"SOCIAL_AUTH_SAML_SP_PRIVATE_KEY": "-----BEGIN PRIVATE KEY-----
redacted
-----END PRIVATE KEY-----"
"SOCIAL_AUTH_SAML_SP_PUBLIC_CERT": "-----BEGIN CERTIFICATE-----
redacted
-----END CERTIFICATE-----"
Next, according to 4.23.3.2.2. Integrating with a SAML Identity Provider — Installing, Configuring, and Running the Open edX Platform documentation, I have configured my Tutor/Edx instance as Service Provider, registered my service at my IdP and added SAML IdP to Edx with the corresponding values(e.g. EntityID, Metadata URL, etc.).
Triple checked, all values correspond, yet the Metadata Ready button is still a red cross(and slug is default
). When I tried to manually run with tutor local run lms ./manage.py lms saml --pull --settings=tutor.production
, the command stops on Fetching https://id.myredacteddomain.com/metadata
. After I pressed Control-C I got this output:
^CTraceback (most recent call last):
File "./manage.py", line 123, in <module>
execute_from_command_line([sys.argv[0]] + django_args)
File "/openedx/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/openedx/venv/lib/python3.8/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/openedx/venv/lib/python3.8/site-packages/django/core/management/base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "/openedx/venv/lib/python3.8/site-packages/django/core/management/base.py", line 364, in execute
output = self.handle(*args, **options)
File "/openedx/edx-platform/common/djangoapps/third_party_auth/management/commands/saml.py", line 32, in handle
total, skipped, attempted, updated, failed, failure_messages = fetch_saml_metadata()
File "/openedx/venv/lib/python3.8/site-packages/celery/local.py", line 191, in __call__
return self._get_current_object()(*a, **kw)
File "/openedx/venv/lib/python3.8/site-packages/celery/app/task.py", line 393, in __call__
return self.run(*args, **kwargs)
File "/openedx/edx-platform/common/djangoapps/third_party_auth/tasks.py", line 84, in fetch_saml_metadata
response = requests.get(url, verify=True) # May raise HTTPError or SSLError or ConnectionError
File "/openedx/venv/lib/python3.8/site-packages/requests/api.py", line 76, in get
return request('get', url, params=params, **kwargs)
File "/openedx/venv/lib/python3.8/site-packages/requests/api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "/openedx/venv/lib/python3.8/site-packages/requests/sessions.py", line 542, in request
resp = self.send(prep, **send_kwargs)
File "/openedx/venv/lib/python3.8/site-packages/requests/sessions.py", line 655, in send
r = adapter.send(request, **kwargs)
File "/openedx/venv/lib/python3.8/site-packages/requests/adapters.py", line 439, in send
resp = conn.urlopen(
File "/openedx/venv/lib/python3.8/site-packages/urllib3/connectionpool.py", line 699, in urlopen
httplib_response = self._make_request(
File "/openedx/venv/lib/python3.8/site-packages/urllib3/connectionpool.py", line 382, in _make_request
self._validate_conn(conn)
File "/openedx/venv/lib/python3.8/site-packages/urllib3/connectionpool.py", line 1010, in _validate_conn
conn.connect()
File "/openedx/venv/lib/python3.8/site-packages/urllib3/connection.py", line 411, in connect
self.sock = ssl_wrap_socket(
File "/openedx/venv/lib/python3.8/site-packages/urllib3/util/ssl_.py", line 420, in ssl_wrap_socket
ssl_sock = _ssl_wrap_socket_impl(
File "/openedx/venv/lib/python3.8/site-packages/urllib3/util/ssl_.py", line 464, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File "/opt/pyenv/versions/3.8.6/lib/python3.8/ssl.py", line 500, in wrap_socket
return self.sslsocket_class._create(
File "/opt/pyenv/versions/3.8.6/lib/python3.8/ssl.py", line 1040, in _create
self.do_handshake()
File "/opt/pyenv/versions/3.8.6/lib/python3.8/ssl.py", line 1309, in do_handshake
self._sslobj.do_handshake()
KeyboardInterrupt
Error: Command failed with status 130: docker-compose -f /home/ubuntu/.local/share/tutor/env/local/docker-compose.yml -f /home/ubuntu/.local/share/tutor/env/local/docker-compose.prod.yml --project-name tutor_local run --rm lms ./manage.py lms saml --pull --settings=tutor.production
Any idea what am I doing wrong? I tried to curl
the metadata.xml and it works, its URL is publicly available.