|
| 1 | +Testing SAML Authentication Locally with MockSAML |
| 2 | +================================================== |
| 3 | + |
| 4 | +This guide walks through setting up and testing SAML authentication in a local Open edX devstack environment using MockSAML.com as a test Identity Provider (IdP). |
| 5 | + |
| 6 | +Overview |
| 7 | +-------- |
| 8 | + |
| 9 | +SAML (Security Assertion Markup Language) authentication in Open edX requires three configuration objects to work together: |
| 10 | + |
| 11 | +1. **SAMLConfiguration**: Configures the Service Provider (SP) metadata - entity ID, keys, and organization info |
| 12 | +2. **SAMLProviderConfig**: Configures a specific Identity Provider (IdP) connection with metadata URL and attribute mappings |
| 13 | +3. **SAMLProviderData**: Stores the IdP's metadata (SSO URL, public key) fetched from the IdP's metadata endpoint |
| 14 | + |
| 15 | +**Critical Requirement**: The SAMLConfiguration object MUST have the slug "default" because this value is hardcoded in the authentication execution path at ``common/djangoapps/third_party_auth/models.py:906``. |
| 16 | + |
| 17 | +Prerequisites |
| 18 | +------------- |
| 19 | + |
| 20 | +* Local Open edX devstack running |
| 21 | +* Access to Django admin at http://localhost:18000/admin/ |
| 22 | +* MockSAML.com account (free service for SAML testing) |
| 23 | + |
| 24 | +Step 1: Configure SAMLConfiguration |
| 25 | +------------------------------------ |
| 26 | + |
| 27 | +The SAMLConfiguration defines your Open edX instance as a SAML Service Provider (SP). |
| 28 | + |
| 29 | +1. Navigate to Django Admin → Third Party Auth → SAML Configurations |
| 30 | +2. Click "Add SAML Configuration" |
| 31 | +3. Configure with these **required** values: |
| 32 | + |
| 33 | + ============ =================================================== |
| 34 | + Field Value |
| 35 | + ============ =================================================== |
| 36 | + Site localhost:18000 |
| 37 | + **Slug** **default** (MUST be "default" - hardcoded in code) |
| 38 | + Entity ID https://saml.example.com/entityid |
| 39 | + Enabled ✓ (checked) |
| 40 | + ============ =================================================== |
| 41 | + |
| 42 | +4. For local testing with MockSAML, you can leave the keys blank. |
| 43 | + |
| 44 | +5. Optionally configure Organization Info (use default or customize): |
| 45 | + |
| 46 | + .. code-block:: json |
| 47 | +
|
| 48 | + { |
| 49 | + "en-US": { |
| 50 | + "url": "http://localhost:18000", |
| 51 | + "displayname": "Local Open edX", |
| 52 | + "name": "localhost" |
| 53 | + } |
| 54 | + } |
| 55 | +
|
| 56 | +6. Click "Save" |
| 57 | + |
| 58 | +Step 2: Configure SAMLProviderConfig |
| 59 | +------------------------------------- |
| 60 | + |
| 61 | +The SAMLProviderConfig connects to a specific SAML Identity Provider (MockSAML in this case). |
| 62 | + |
| 63 | +1. Navigate to Django Admin → Third Party Auth → Provider Configuration (SAML IdPs) |
| 64 | +2. Click "Add Provider Configuration (SAML IdP)" |
| 65 | +3. Configure with these values: |
| 66 | + |
| 67 | + ========================= =================================================== |
| 68 | + Field Value |
| 69 | + ========================= =================================================== |
| 70 | + Name Test Localhost (or any descriptive name) |
| 71 | + Slug default (to match test URLs) |
| 72 | + Backend Name tpa-saml |
| 73 | + Entity ID https://saml.example.com/entityid |
| 74 | + Metadata Source https://mocksaml.com/api/saml/metadata |
| 75 | + Site localhost:18000 |
| 76 | + SAML Configuration Select the SAMLConfiguration created in Step 1 |
| 77 | + Enabled ✓ (checked) |
| 78 | + Visible ☐ (unchecked for testing) |
| 79 | + Skip hinted login dialog ✓ (checked - recommended) |
| 80 | + Skip registration form ✓ (checked - recommended) |
| 81 | + Skip email verification ✓ (checked - recommended) |
| 82 | + Send to registration first ✓ (checked - recommended) |
| 83 | + ========================= =================================================== |
| 84 | + |
| 85 | +4. Leave all attribute mappings (User ID, Email, Full Name, etc.) blank to use defaults |
| 86 | +5. Click "Save" |
| 87 | + |
| 88 | +**Important**: The Entity ID in SAMLProviderConfig MUST match the Entity ID in SAMLConfiguration. |
| 89 | + |
| 90 | +Step 3: Set IdP Data |
| 91 | +-------------------- |
| 92 | + |
| 93 | +The SAMLProviderData stores metadata from the Identity Provider (MockSAML), create a record with |
| 94 | + |
| 95 | +* **Entity ID**: https://saml.example.com/entityid |
| 96 | +* **SSO URL**: https://mocksaml.com/api/saml/sso |
| 97 | +* **Public Key**: The IdP's signing certificate |
| 98 | +* **Expires At**: Set to 1 year from fetch time |
| 99 | + |
| 100 | + |
| 101 | +Step 4: Test SAML Authentication |
| 102 | +--------------------------------- |
| 103 | + |
| 104 | +1. Navigate to: http://localhost:18000/auth/idp_redirect/saml-default |
| 105 | +2. You should be redirected to MockSAML.com |
| 106 | +3. Complete the authentication on MockSAML - just click "Sign In" with whatever is in the form. |
| 107 | +4. You should be redirected back to Open edX |
| 108 | +5. If this is a new user, you'll see the registration form |
| 109 | +6. After registration, you should be logged in |
| 110 | + |
| 111 | +Expected Behavior |
| 112 | +^^^^^^^^^^^^^^^^^ |
| 113 | + |
| 114 | +1. Initial redirect to MockSAML (https://mocksaml.com/api/saml/sso) |
| 115 | +2. MockSAML displays the login page |
| 116 | +3. After authentication, MockSAML POSTs the SAML assertion back to Open edX |
| 117 | +4. Open edX validates the assertion and creates/logs in the user |
| 118 | +5. User is redirected to the dashboard or registration form (if new user) |
| 119 | + |
| 120 | +Reference Configuration |
| 121 | +----------------------- |
| 122 | + |
| 123 | +Here's a summary of a working test configuration: |
| 124 | + |
| 125 | +**SAMLConfiguration** (id=6): |
| 126 | + |
| 127 | +* Site: localhost:18000 |
| 128 | +* Slug: **default** |
| 129 | +* Entity ID: https://saml.example.com/entityid |
| 130 | +* Enabled: True |
| 131 | + |
| 132 | +**SAMLProviderConfig** (id=11): |
| 133 | + |
| 134 | +* Name: Test Localhost |
| 135 | +* Slug: default |
| 136 | +* Entity ID: https://saml.example.com/entityid |
| 137 | +* Metadata Source: https://mocksaml.com/api/saml/metadata |
| 138 | +* Backend Name: tpa-saml |
| 139 | +* Site: localhost:18000 |
| 140 | +* SAML Configuration: → SAMLConfiguration (id=6) |
| 141 | +* Enabled: True |
| 142 | + |
| 143 | +**SAMLProviderData** (id=3): |
| 144 | + |
| 145 | +* Entity ID: https://saml.example.com/entityid |
| 146 | +* SSO URL: https://mocksaml.com/api/saml/sso |
| 147 | +* Public Key: (certificate from MockSAML metadata) |
| 148 | +* Fetched At: 2026-02-27 18:05:40+00:00 |
| 149 | +* Expires At: 2027-02-27 18:05:41+00:00 |
| 150 | +* Valid: True |
| 151 | + |
| 152 | +**MockSAML Configuration**: |
| 153 | + |
| 154 | +* SP Entity ID: https://saml.example.com/entityid |
| 155 | +* ACS URL: http://localhost:18000/auth/complete/tpa-saml/ |
| 156 | +* Test User Attributes: email, firstName, lastName, uid |
0 commit comments