SAML IdP integration into Open edX

Hi there. I’ve got openedx olive deployed with tutor. I want to add my own account management system as IdP for openedx, making openedx the service provider. To do so, I followed the official documentation. Now I can see the login with SSO button on login page but when I click on it, I get the Unknown System Entity (https://edx.smartstars.ir/auth/saml/metadata.xml) error from the IdP.

My IdP is implemented using djangosaml2idp library and it’s working fine with a sample service provider implemented using djangosaml2 library.

In openedx django admin, in Provider Configuration (SAML IdP), I set both Entity ID and Metadata source to https://sso.smartstars.ir/idp/metadata/ and in SAML Configuration, Entity ID is set to https://edx.smartstars.ir/auth/saml/metadata.xml. For both SAML configuration and Proivder Configuration, Site is set to edx.smartstars.ir and Slug is set to default.

I did a little research on SAML implementation in openedx and it seems SAML SP side is implemented using python3-saml package. So my question is, do I have to use any special package / format for IdP (is the current IdP implemented with djangosaml2idp incompatible with openedx saml sp system and I should stop using djangosaml2idp)? Have I made any mistakes in the configurations set in django admin? It’ll be great if someone explain the Entity ID thing to me. Should I provide it with the metadata URL or the IdP instance URL or what?

Sorry for the long post and if the topic is wrong / unprecise. It’s my first time creating a topic here :slight_smile: Thanks in advance for any help :slight_smile:

The Entity ID is just a URL that acts as an ID for your SP and for your IdP. You have made it the same as the metadata URL in each case, which is unusual but should work totally fine. I don’t see anything wrong with your configuration from a quick glance.

It sounds like to need to register the Open edX SP with your Django IdP. In other words, it’s correct on the Open edX side, but you need to fix the IdP.

I think what you’re missing is this step from the djangosaml2idp README:

Place the metadata xml from that SP in the location specified in the config dict (sp_metadata.xml in the example above).

So download https://edx.smartstars.ir/auth/saml/metadata.xml and save that into the specified place for your djangosaml2idp config.

Actually I had configured openedx as SP in my IdP admin panel but forgot to mention it. The configuration look like this:

Is this configuration correct in your opinion? Also I’d be really grateful if you’d take a look at this sample SP configuration written in the djangosaml2idp repository. The sample SP that I wrote (which worked fine with my IdP) had this settings. So based on this example configuration, do you think I need any extra configuration or implementation on my openedx side?

If you know any better (more correct or easier) way for this whole saml IdP integration thing, I’d be happy to learn. Actually we’re at the start of our development phase so replacing stuff and adopting new / better approaches is both easy and encouraged. Our only issue is that we want to keep the user data to our self not any remote online third party IdP. We also need to customise the user model and auth flow so we thought implementing an account management system would be the better way compared to changing (forking) the openedx code.

It looks correct to me!

You can also try using https://samltest.id/ as an IdP to test your Open edX SP setup.

Sorry for the gap. My issue changed a little bit. Now I’m not getting the UnknownSystemEntity error but still it’s not possible to log in. when I click on the “login with SSO” button, it redirects to the sso at /idp/sso/login/process and then redirects back to openedx login page (not logged in). It shows no error message on the page or in http responses. But going through the log I found Authentication failed: SAML login failed: ['invalid_response'] (No Signature found. SAML Response rejected) message. The log:

tutor_local-lms-1 | 2023-07-24 12:16:49,650 INFO 7 [tracking] [user None] [ip 15.188.191.90] logger.py:41 - {"name": "/auth/login/tpa-saml/", "context": {"user_id": null, "path": "/auth/login/tpa-saml/", "course_id": "", "org_id": "", "enterprise_uuid": ""}, "username": "", "session": "bf11a5bc9d4c13a03b3cbb8b2e7f2c93", "ip": "15.188.191.90", "agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36", "host": "edx.smartstars.ir", "referer": "https://apps.edx.smartstars.ir/", "accept_language": "en-GB,en-US;q=0.9,en;q=0.8,fa;q=0.7", "event": "{\"GET\": {\"auth_entry\": [\"login\"], \"next\": [\"/dashboard\"], \"idp\": [\"default\"]}, \"POST\": {}}", "time": "2023-07-24T12:16:49.648087+00:00", "event_type": "/auth/login/tpa-saml/", "event_source": "server", "page": null}
tutor_local-lms-1 | 2023-07-24 12:16:49,729 INFO 7 [common.djangoapps.third_party_auth.saml] [user None] [ip 15.188.191.90] saml.py:178 - SAML login request for IdP default. Data: <QueryDict: {'auth_entry': ['login'], 'next': ['/dashboard'], 'idp': ['default']}>. Next url /dashboard. XML is:
tutor_local-lms-1 | <samlp:AuthnRequest
tutor_local-lms-1 |   xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
tutor_local-lms-1 |   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
tutor_local-lms-1 |   ID="ONELOGIN_bbe26a42d512c70b71f6df402f8911326ddd078c"
tutor_local-lms-1 |   Version="2.0"
tutor_local-lms-1 |     ProviderName="Sharif Star"
tutor_local-lms-1 |   IssueInstant="2023-07-24T12:16:49Z"
tutor_local-lms-1 |   Destination="https://sso.smartstars.ir/idp/sso/redirect/"
tutor_local-lms-1 |   ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
tutor_local-lms-1 |   AssertionConsumerServiceURL="https://edx.smartstars.ir/auth/complete/tpa-saml/">
tutor_local-lms-1 |     <saml:Issuer>https://edx.smartstars.ir/auth/saml/metadata.xml</saml:Issuer>
tutor_local-lms-1 |     <samlp:NameIDPolicy
tutor_local-lms-1 |         Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
tutor_local-lms-1 |         AllowCreate="true" />
tutor_local-lms-1 |     <samlp:RequestedAuthnContext Comparison="exact">
tutor_local-lms-1 |         <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
tutor_local-lms-1 |     </samlp:RequestedAuthnContext>
tutor_local-lms-1 | </samlp:AuthnRequest>
tutor_local-lms-1 | [pid: 7|app: 0|req: 201/644] 172.18.0.2 () {60 vars in 1540 bytes} [Mon Jul 24 12:16:49 2023] GET /auth/login/tpa-saml/?auth_entry=login&next=%2Fdashboard&idp=default => generated 0 bytes in 175 msecs (HTTP/1.1 302) 9 headers in 1347 bytes (1 switches on core 0)
tutor_local-caddy-1 | {"level":"info","ts":1690201009.7466197,"logger":"http.log.access.log0","msg":"handled request","request":{"remote_ip":"15.188.191.90","remote_port":"42264","proto":"HTTP/2.0","method":"GET","host":"edx.smartstars.ir","uri":"/auth/login/tpa-saml/?auth_entry=login&next=%2Fdashboard&idp=default","tls":{"resumed":true,"version":772,"cipher_suite":4867,"proto":"h2","server_name":"edx.smartstars.ir"}},"user_id":"","duration":0.191210703,"size":0,"status":302}
tutor_local-lms-1 | 2023-07-24 12:16:52,831 INFO 19 [tracking] [user None] [ip 15.188.191.90] logger.py:41 - {"name": "/auth/complete/tpa-saml/", "context": {"user_id": null, "path": "/auth/complete/tpa-saml/", "course_id": "", "org_id": "", "enterprise_uuid": ""}, "username": "", "session": "bf11a5bc9d4c13a03b3cbb8b2e7f2c93", "ip": "15.188.191.90", "agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36", "host": "edx.smartstars.ir", "referer": "", "accept_language": "en-GB,en-US;q=0.9,en;q=0.8,fa;q=0.7", "event": "{\"GET\": {}, \"POST\": {\"RelayState\": [\"default\"], \"SAMLResponse\": [\"PG5zMDpSZXNwb25zZSB4bWxuczpuczA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgeG1sbnM6bnMxPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiBJRD0iaWQtVXRYWXl0cmp1eW5Pcms1QXYiIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fYmJlMjZhNDJkNTEyYzcwYjcxZjZkZjQwMmY4OTExMzI2ZGRkMDc4YyIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMjMtMDctMjRUMTI6MTY6NTJaIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9lZHguc2", "time": "2023-07-24T12:16:52.829045+00:00", "event_type": "/auth/complete/tpa-saml/", "event_source": "server", "page": null}
tutor_local-lms-1 | No Signature found. SAML Response rejected
tutor_local-lms-1 | 2023-07-24 12:16:52,943 INFO 19 [common.djangoapps.third_party_auth.saml] [user None] [ip 15.188.191.90] saml.py:178 - SAML login response for IdP default. Data: <QueryDict: {'RelayState': ['default'], 'SAMLResponse': ['PG5zMDpSZXNwb25zZSB4bWxuczpuczA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgeG1sbnM6bnMxPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiBJRD0iaWQtVXRYWXl0cmp1eW5Pcms1QXYiIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fYmJlMjZhNDJkNTEyYzcwYjcxZjZkZjQwMmY4OTExMzI2ZGRkMDc4YyIgVmVyc2lvbj0iMi4wIiBJc3N1ZUluc3RhbnQ9IjIwMjMtMDctMjRUMTI6MTY6NTJaIiBEZXN0aW5hdGlvbj0iaHR0cHM6Ly9lZHguc21hcnRzdGFycy5pci9hdXRoL2NvbXBsZXRlL3RwYS1zYW1sLyI+PG5zMTpJc3N1ZXIgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6bmFtZWlkLWZvcm1hdDplbnRpdHkiPmh0dHBzOi8vc3NvLnNtYXJ0c3RhcnMuaXIvaWRwL21ldGFkYXRhLzwvbnMxOklzc3Vlcj48bnMwOlN0YXR1cz48bnMwOlN0YXR1c0NvZGUgVmFsdWU9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpzdGF0dXM6U3VjY2VzcyIgLz48L25zMDpTdGF0dXM+PG5zMTpBc3NlcnRpb24gVmVyc2lvbj0iMi4wIiBJRD0iaWQtaGRZVkt6NHZQN1JIRTd0S3oiIElzc3VlSW5zdGFudD0iMjAyMy0wNy0yNFQxMjoxNjo1MloiPjxuczE6SXNzdWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOm5hbWVpZC1mb3JtYXQ6ZW50aXR5Ij5odHRwczovL3Nzby5zbWFydHN0YXJzLmlyL2lkcC9tZXRhZGF0YS88L25zMTpJc3N1ZXI+PG5zMTpTdWJqZWN0PjxuczE6TmFtZUlEIFNQTmFtZVF1YWxpZmllcj0iaHR0cHM6Ly9lZHguc21hcnRzdGFycy5pci9hdXRoL3NhbWwvbWV0YWRhdGEueG1sIiBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OnVuc3BlY2lmaWVkIj5GYXRlbWVLaG9kYXlhcmk8L25zMTpOYW1lSUQ+PG5zMTpTdWJqZWN0Q29uZmlybWF0aW9uIE1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlciI+PG5zMTpTdWJqZWN0Q29uZmlybWF0aW9uRGF0YSBOb3RPbk9yQWZ0ZXI9IjIwMjMtMDctMjRUMTM6MTY6NTJaIiBSZWNpcGllbnQ9Imh0dHBzOi8vZWR4LnNtYXJ0c3RhcnMuaXIvYXV0aC9jb21wbGV0ZS90cGEtc2FtbC8iIEluUmVzcG9uc2VUbz0iT05FTE9HSU5fYmJlMjZhNDJkNTEyYzcwYjcxZjZkZjQwMmY4OTExMzI2ZGRkMDc4YyIgLz48L25zMTpTdWJqZWN0Q29uZmlybWF0aW9uPjwvbnMxOlN1YmplY3Q+PG5zMTpDb25kaXRpb25zIE5vdEJlZm9yZT0iMjAyMy0wNy0yNFQxMjoxNjo1MloiIE5vdE9uT3JBZnRlcj0iMjAyMy0wNy0yNFQxMzoxNjo1MloiPjxuczE6QXVkaWVuY2VSZXN0cmljdGlvbj48bnMxOkF1ZGllbmNlPmh0dHBzOi8vZWR4LnNtYXJ0c3RhcnMuaXIvYXV0aC9zYW1sL21ldGFkYXRhLnhtbDwvbnMxOkF1ZGllbmNlPjwvbnMxOkF1ZGllbmNlUmVzdHJpY3Rpb24+PC9uczE6Q29uZGl0aW9ucz48bnMxOkF1dGhuU3RhdGVtZW50IEF1dGhuSW5zdGFudD0iMjAyMy0wNy0yNFQxMjoxNjo1MloiIFNlc3Npb25JbmRleD0iaWQtc1dqdXBRVEhaSGhFRDN2MU4iPjxuczE6QXV0aG5Db250ZXh0PjxuczE6QXV0aG5Db250ZXh0Q2xhc3NSZWY+dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFjOmNsYXNzZXM6UGFzc3dvcmQ8L25zMTpBdXRobkNvbnRleHRDbGFzc1JlZj48L25zMTpBdXRobkNvbnRleHQ+PC9uczE6QXV0aG5TdGF0ZW1lbnQ+PG5zMTpBdHRyaWJ1dGVTdGF0ZW1lbnQ+PG5zMTpBdHRyaWJ1dGUgTmFtZT0idXJuOm9pZDoxLjIuODQwLjExMzU0OS4xLjkuMS4xIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OnVyaSIgRnJpZW5kbHlOYW1lPSJlbWFpbCI+PG5zMTpBdHRyaWJ1dGVWYWx1ZSB4c2k6dHlwZT0ieHM6c3RyaW5nIiB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPmZhdGVtZS5raG9kYXlhcmk5N0BnbWFpbC5jb208L25zMTpBdHRyaWJ1dGVWYWx1ZT48L25zMTpBdHRyaWJ1dGU+PG5zMTpBdHRyaWJ1dGUgTmFtZT0iZmlyc3RfbmFtZSIgTmFtZUZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDp1cmkiPjxuczE6QXR0cmlidXRlVmFsdWUgeHNpOnR5cGU9InhzOnN0cmluZyIgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiAvPjwvbnMxOkF0dHJpYnV0ZT48bnMxOkF0dHJpYnV0ZSBOYW1lPSJsYXN0X25hbWUiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6dXJpIj48bnMxOkF0dHJpYnV0ZVZhbHVlIHhzaTp0eXBlPSJ4czpzdHJpbmciIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgLz48L25zMTpBdHRyaWJ1dGU+PG5zMTpBdHRyaWJ1dGUgTmFtZT0iaXNfc3RhZmYiIE5hbWVGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphdHRybmFtZS1mb3JtYXQ6dXJpIj48bnMxOkF0dHJpYnV0ZVZhbHVlIHhzaTp0eXBlPSJ4czpib29sZWFuIiB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPnRydWU8L25zMTpBdHRyaWJ1dGVWYWx1ZT48L25zMTpBdHRyaWJ1dGU+PG5zMTpBdHRyaWJ1dGUgTmFtZT0iaXNfc3VwZXJ1c2VyIiBOYW1lRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OnVyaSI+PG5zMTpBdHRyaWJ1dGVWYWx1ZSB4c2k6dHlwZT0ieHM6Ym9vbGVhbiIgeG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIj50cnVlPC9uczE6QXR0cmlidXRlVmFsdWU+PC9uczE6QXR0cmlidXRlPjwvbnMxOkF0dHJpYnV0ZVN0YXRlbWVudD48L25zMTpBc3NlcnRpb24+PC9uczA6UmVzcG9uc2U+']}>. Next url /dashboard. XML is:
tutor_local-lms-1 | <ns0:Response xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:ns1="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="id-UtXYytrjuynOrk5Av" InResponseTo="ONELOGIN_bbe26a42d512c70b71f6df402f8911326ddd078c" Version="2.0" IssueInstant="2023-07-24T12:16:52Z" Destination="https://edx.smartstars.ir/auth/complete/tpa-saml/"><ns1:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://sso.smartstars.ir/idp/metadata/</ns1:Issuer><ns0:Status><ns0:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></ns0:Status><ns1:Assertion Version="2.0" ID="id-hdYVKz4vP7RHE7tKz" IssueInstant="2023-07-24T12:16:52Z"><ns1:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://sso.smartstars.ir/idp/metadata/</ns1:Issuer><ns1:Subject><ns1:NameID SPNameQualifier="https://edx.smartstars.ir/auth/saml/metadata.xml" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">FatemeKhodayari</ns1:NameID><ns1:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><ns1:SubjectConfirmationData NotOnOrAfter="2023-07-24T13:16:52Z" Recipient="https://edx.smartstars.ir/auth/complete/tpa-saml/" InResponseTo="ONELOGIN_bbe26a42d512c70b71f6df402f8911326ddd078c"/></ns1:SubjectConfirmation></ns1:Subject><ns1:Conditions NotBefore="2023-07-24T12:16:52Z" NotOnOrAfter="2023-07-24T13:16:52Z"><ns1:AudienceRestriction><ns1:Audience>https://edx.smartstars.ir/auth/saml/metadata.xml</ns1:Audience></ns1:AudienceRestriction></ns1:Conditions><ns1:AuthnStatement AuthnInstant="2023-07-24T12:16:52Z" SessionIndex="id-sWjupQTHZHhED3v1N"><ns1:AuthnContext><ns1:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</ns1:AuthnContextClassRef></ns1:AuthnContext></ns1:AuthnStatement><ns1:AttributeStatement><ns1:Attribute Name="urn:oid:1.2.840.113549.1.9.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="email"><ns1:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">fateme.khodayari97@gmail.com</ns1:AttributeValue></ns1:Attribute><ns1:Attribute Name="first_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><ns1:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string"/></ns1:Attribute><ns1:Attribute Name="last_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><ns1:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string"/></ns1:Attribute><ns1:Attribute Name="is_staff" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><ns1:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:boolean">true</ns1:AttributeValue></ns1:Attribute><ns1:Attribute Name="is_superuser" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"><ns1:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:boolean">true</ns1:AttributeValue></ns1:Attribute></ns1:AttributeStatement></ns1:Assertion></ns0:Response>
tutor_local-lms-1 | 2023-07-24 12:16:52,950 INFO 19 [social] [user None] [ip 15.188.191.90] middleware.py:37 - Authentication failed: SAML login failed: ['invalid_response'] (No Signature found. SAML Response rejected)

Do you happen to know what’s the issue?

This error indicates that the IdP is not signing the SAML <ns0:Response> XML. The Response should contain a digital signature of the XML Assertion, but if the IdP is misconfigured, the signature will be missing. Indeed, I can see the <ns0:Response>...</ns0:Response> from your logs does not contain any signature. However, I don’t know enough about your particular IdP to know what setting you need to change.

Thanks @braden. I solved the signing issue but I get this error:

2023-08-05 14:18:14,932 ERROR 19 [django.request] [user None] [ip 178.131.186.150] log.py:224 - Internal Server Error: /auth/complete/tpa-saml/
Traceback (most recent call last):
  File "/openedx/edx-platform/common/djangoapps/third_party_auth/saml.py", line 92, in get_user_id
    return super().get_user_id(details, response)
  File "/openedx/venv/lib/python3.8/site-packages/social_core/backends/saml.py", line 304, in get_user_id
    uid = idp.get_user_permanent_id(response['attributes'])
  File "/openedx/venv/lib/python3.8/site-packages/social_core/backends/saml.py", line 45, in get_user_permanent_id
    uid = attributes[self.conf.get('attr_user_permanent_id', OID_USERID)]
KeyError: 'urn:oid:0.9.2342.19200300.100.1.1'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/openedx/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/openedx/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/pyenv/versions/3.8.12/lib/python3.8/contextlib.py", line 75, in inner
    return func(*args, **kwds)
  File "/openedx/venv/lib/python3.8/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/social_django/utils.py", line 46, in wrapper
    return func(request, backend, *args, **kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/social_django/views.py", line 31, in complete
    return do_complete(request.backend, _do_login, user=request.user,
  File "/openedx/venv/lib/python3.8/site-packages/social_core/actions.py", line 45, in do_complete
    user = backend.complete(user=user, *args, **kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/social_core/backends/base.py", line 40, in complete
    return self.auth_complete(*args, **kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/social_core/backends/saml.py", line 332, in auth_complete
    return self.strategy.authenticate(*args, **kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/social_django/strategy.py", line 105, in authenticate
    return authenticate(*args, **kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/django/views/decorators/debug.py", line 42, in sensitive_variables_wrapper
    return func(*func_args, **func_kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/django/contrib/auth/__init__.py", line 76, in authenticate
    user = backend.authenticate(request, **credentials)
  File "/openedx/venv/lib/python3.8/site-packages/social_core/backends/base.py", line 80, in authenticate
    return self.pipeline(pipeline, *args, **kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/social_core/backends/base.py", line 83, in pipeline
    out = self.run_pipeline(pipeline, pipeline_index, *args, **kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/social_core/backends/base.py", line 113, in run_pipeline
    result = func(*args, **out) or {}
  File "/openedx/venv/lib/python3.8/site-packages/social_core/pipeline/social_auth.py", line 9, in social_uid
    return {'uid': backend.get_user_id(details, response)}
  File "/openedx/edx-platform/common/djangoapps/third_party_auth/saml.py", line 97, in get_user_id
    message=ex.message,  # lint-amnesty, pylint: disable=no-member
AttributeError: 'KeyError' object has no attribute 'message'

I validated my saml response here and it said that the reponse is valid. Also I used this tool for extracting info sent in saml idp response which looks like this

I’ve tried changing the User ID Attribute to both urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified and urn.oid:0.9.2342.19200300.100.1.1 in both idp settings and openedx saml idp configuration. When I set name id format to only urn.oid:0.9.2342.19200300.100.1.1 in my idp, I get an error at the start of login process, saying: ImproperlyConfigured: SP requested a name_id_format that is not supported in the IDP: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified.

When I put only the unspecified one or even both of them in the idp settings, edx returns the error mentioned above. When I set User ID Attribute to urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified in openedx saml idp configuration, the only difference it makes is changing part of the error message from urn.oid:0.9.2342.19200300.100.1.1 to urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified.

Solved it! I set the User ID Attribute in openedx saml provider configuration, to urn:oid:1.2.840.113549.1.9.1.1 and it just worked! Later I changed my IdP to send username as uid and changed User ID Attribute to urn:oid:0.9.2342.19200300.100.1.1

@FatemeKhodayari and @braden , I am working to develop an application on the top of opendex site (mylearning.com) and run application on sub-site (sub.mylearning.com). How can I set SSO (SAML) for this, where an identity provider is edx-site?. It seems like it is just reverse idea of what you were talking here. I set up the configuration using this tutorial. But it does not work. I cannot download any metadata. It is empty. I appriciate for any help !!.

@hkhanal01 Open edX cannot act as an Identity Provider using, SAML, but it can using OAuth - please see Open edX as SSO IdP . And if you have further questions about that, please start a new thread - it’s not really related to the topic of this thread.

1 Like

@braden thanks a lot. Django Oauth works.