IdentityPython / djangosaml2

Django SAML2 Service Provider based on pySAML2
Apache License 2.0
258 stars 143 forks source link

Issue with SimpleSAMLphp 1.19.8 #366

Open rmincling opened 1 year ago

rmincling commented 1 year ago

Hi,

I'm having some issues with correctly logging in with this test docker image https://github.com/kristophjunge/docker-test-saml-idp . I can bring up the SimpleSAMLphp login page via django and it successfully logs in on SimpleSAMLphp server with test user data. However, when I'm trying to parse the response from SimpleSAMLphp, the response.assertion and response.assertions array are both blank, as well as response.ava. This causes the error below:

`saml2.response.StatusInvalidAuthnResponseStatement: The Authn Response Statement is not valid
ERROR 2023-03-23 16:56:56,871 log 14996 123145691701248 Internal Server Error: /saml2_auth/acs/
Traceback (most recent call last):
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/asgiref/sync.py", line 486, in thread_handler
    raise exc_info[1]
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/django/core/handlers/exception.py", line 43, in inner
    response = await get_response(request)
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/django/core/handlers/base.py", line 253, in _get_response_async
    response = await wrapped_callback(
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/asgiref/sync.py", line 448, in __call__
    ret = await asyncio.wait_for(future, timeout=None)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/tasks.py", line 442, in wait_for
    return await fut
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/asgiref/current_thread_executor.py", line 22, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/asgiref/sync.py", line 490, in thread_handler
    return func(*args, **kwargs)
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/sentry_sdk/integrations/django/views.py", line 85, in sentry_wrapped_callback
    return callback(request, *args, **kwargs)
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/django/views/generic/base.py", line 103, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/django/utils/decorators.py", line 46, in _wrapper
    return bound_method(*args, **kwargs)
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 55, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/django/views/generic/base.py", line 142, in dispatch
    return handler(request, *args, **kwargs)
  File "/Users/robertm/dev/platform/d3_platform/src/platform_v2/accounts/views.py", line 281, in post
    session_info = response.session_info()
  File "/Users/robertm/dev/platform/d3_platform/lib/python3.9/site-packages/saml2/response.py", line 1099, in session_info
    raise StatusInvalidAuthnResponseStatement("The Authn Response Statement is not valid")`

I was hoping you could please advise as to what may be the issue. It is worth noting this exact same docker image works with django-saml2-auth (but an older version), I am migrating over to your well defined package.

Regards,

Rob

peppelinux commented 1 year ago

it seems that you have to map the user attributes and the format of these in

https://pysaml2.readthedocs.io/en/latest/howto/config.html#requested-attribute-name-format

and

https://github.com/IdentityPython/djangosaml2/blob/master/djangosaml2/tests/attribute-maps/saml_uri.py

rmincling commented 1 year ago

So heres my config

PHP config

<?php

$config = array(
    'admin' => array(
        'core:AdminPassword',
    ),
    'example-userpass' => array(
        'exampleauth:UserPass',
        'SamlUserA:Testing123!' => array(
            'uid' => array('1'),
            'email' => 'saml.a@incling.com',
            'first_name' => 'First A',
            'last_name' => 'Last A',
        ),
        'SamlUserB:Testing123!' => array(
            'uid' => array('2'),
            'email' => 'saml.b@incling.com',
            'first_name' => 'First B',
            'last_name' => 'Last B',
        ),
    ),
);

and in my settings.py

SAML_ATTRIBUTE_MAPPING = {
    'username': ('username', ),
    'email': ('email', ),
    'first_name': ('first_name', ),
    'last_name': ('last_name', ),
}

and

SAML_CONFIG = {
  'xmlsec_binary': '/usr/local/bin/xmlsec1',

  'entityid': 'http://127.0.0.1:2222/saml2_auth/acs/',

  'allow_unknown_attributes': True,

  'service': {
      'sp': {
          'name': 'SimpleSAMLphp',
          'name_id_format': saml2.saml.NAMEID_FORMAT_TRANSIENT,
          'requested_attribute_name_format': saml2.saml.NAMEID_FORMAT_TRANSIENT,
          'name_format': saml2.saml.NAMEID_FORMAT_TRANSIENT,

          'endpoints': {
              'assertion_consumer_service': [
                  ('http://127.0.0.1:2222/saml2_auth/acs/',
                   saml2.BINDING_HTTP_REDIRECT),
                  ],
              },

          'signing_algorithm':  saml2.xmldsig.SIG_RSA_SHA256,
          'digest_algorithm':  saml2.xmldsig.DIGEST_SHA256,

          'force_authn': False,

          'name_id_format_allow_create': False,

          'required_attributes': [
              'username',
              'first_name',
              'last_name',
              'email'
          ],

          'optional_attributes': ['eduPersonAffiliation'],

          'want_response_signed': False,
          'authn_requests_signed': False,
          'logout_requests_signed': True,
          'want_assertions_signed': False,
          'only_use_keys_in_metadata': False,
          'allow_unsolicited': True,
          },
      },

  'metadata': {
      'remote': [{"url": "http://127.0.0.1:8080/simplesaml/saml2/idp/metadata.php"},],
      },

  'debug': 1,
  }

Am I missing something?

rmincling commented 1 year ago

Forgot to mention I'm on Django==4.1.7

peppelinux commented 1 year ago

look at this https://pysaml2.readthedocs.io/en/latest/howto/config.html#requested-attribute-name-format

it depends on which format your IDP uses, if BASIC or URI

here an example of attribute mapping with uri https://github.com/IdentityPython/djangosaml2/blob/master/djangosaml2/tests/attribute-maps/django_saml_uri.py

please check if you have to configure it with uri or basic, then create your attribute-map file and put in a path configured in attribute_map_dir

rmincling commented 1 year ago

oh, so attribute_map_dir is mandatory? Apologies, this is new to me, I've inherited a Django setup that was using django-saml2-auth which didn't seem to need this defined.

rmincling commented 1 year ago

So this is the IDP metadata output from the IDP

<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="http://127.0.0.1:8080/simplesaml/saml2/idp/metadata.php">
<md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIIDXTCCAkWgAwIBAgIJALmVVuDWu4NYMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTYxMjMxMTQzNDQ3WhcNNDgwNjI1MTQzNDQ3WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzUCFozgNb1h1M0jzNRSCjhOBnR+uVbVpaWfXYIR+AhWDdEe5ryY+CgavOg8bfLybyzFdehlYdDRgkedEB/GjG8aJw06l0qF4jDOAw0kEygWCu2mcH7XOxRt+YAH3TVHa/Hu1W3WjzkobqqqLQ8gkKWWM27fOgAZ6GieaJBN6VBSMMcPey3HWLBmc+TYJmv1dbaO2jHhKh8pfKw0W12VM8P1PIO8gv4Phu/uuJYieBWKixBEyy0lHjyixYFCR12xdh4CA47q958ZRGnnDUGFVE1QhgRacJCOZ9bd5t9mr8KLaVBYTCJo5ERE8jymab5dPqe5qKfJsCZiqWglbjUo9twIDAQABo1AwTjAdBgNVHQ4EFgQUxpuwcs/CYQOyui+r1G+3KxBNhxkwHwYDVR0jBBgwFoAUxpuwcs/CYQOyui+r1G+3KxBNhxkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAAiWUKs/2x/viNCKi3Y6blEuCtAGhzOOZ9EjrvJ8+COH3Rag3tVBWrcBZ3/uhhPq5gy9lqw4OkvEws99/5jFsX1FJ6MKBgqfuy7yh5s1YfM0ANHYczMmYpZeAcQf2CGAaVfwTTfSlzNLsF2lW/ly7yapFzlYSJLGoVE+OHEu8g5SlNACUEfkXw+5Eghh+KzlIN7R6Q7r2ixWNFBC/jWf7NKUfJyX8qIG5md1YUeT6GBW9Bm2/1/RiO24JTaYlfLdKK9TYb8sG5B+OLab2DImG99CJ25RkAcSobWNF5zD0O6lgOo3cEdB/ksCq3hmtlC/DlLZ/D8CJ+7VuZnS1rR2naQ==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIIDXTCCAkWgAwIBAgIJALmVVuDWu4NYMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTYxMjMxMTQzNDQ3WhcNNDgwNjI1MTQzNDQ3WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzUCFozgNb1h1M0jzNRSCjhOBnR+uVbVpaWfXYIR+AhWDdEe5ryY+CgavOg8bfLybyzFdehlYdDRgkedEB/GjG8aJw06l0qF4jDOAw0kEygWCu2mcH7XOxRt+YAH3TVHa/Hu1W3WjzkobqqqLQ8gkKWWM27fOgAZ6GieaJBN6VBSMMcPey3HWLBmc+TYJmv1dbaO2jHhKh8pfKw0W12VM8P1PIO8gv4Phu/uuJYieBWKixBEyy0lHjyixYFCR12xdh4CA47q958ZRGnnDUGFVE1QhgRacJCOZ9bd5t9mr8KLaVBYTCJo5ERE8jymab5dPqe5qKfJsCZiqWglbjUo9twIDAQABo1AwTjAdBgNVHQ4EFgQUxpuwcs/CYQOyui+r1G+3KxBNhxkwHwYDVR0jBBgwFoAUxpuwcs/CYQOyui+r1G+3KxBNhxkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAAiWUKs/2x/viNCKi3Y6blEuCtAGhzOOZ9EjrvJ8+COH3Rag3tVBWrcBZ3/uhhPq5gy9lqw4OkvEws99/5jFsX1FJ6MKBgqfuy7yh5s1YfM0ANHYczMmYpZeAcQf2CGAaVfwTTfSlzNLsF2lW/ly7yapFzlYSJLGoVE+OHEu8g5SlNACUEfkXw+5Eghh+KzlIN7R6Q7r2ixWNFBC/jWf7NKUfJyX8qIG5md1YUeT6GBW9Bm2/1/RiO24JTaYlfLdKK9TYb8sG5B+OLab2DImG99CJ25RkAcSobWNF5zD0O6lgOo3cEdB/ksCq3hmtlC/DlLZ/D8CJ+7VuZnS1rR2naQ==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://127.0.0.1:8080/simplesaml/saml2/idp/SingleLogoutService.php"/>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://127.0.0.1:8080/simplesaml/saml2/idp/SSOService.php"/>
</md:IDPSSODescriptor>
</md:EntityDescriptor>

No format is stated, so does it default to URI?

peppelinux commented 1 year ago

please share also an example response

rmincling commented 1 year ago

Sure, here you go, it looks like its using basic formatting, I don't seem to be able to get the formatting of my attribute map file correct? The response.ava and assertion/assertion attributes are all empty, even though the raw SAML response has the authenticated user data in the AttributeStatement.

Its also worth noting that i receive this exact same response in my previous setup using django-saml2-auth, Django 2.22 and pysaml2 7.4.1, the SAML response object has ava, assertion and assertions attributes all populated. So its definitely something I'm missing when setting this all up using djangosaml2.

<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_b215f220769ed51fbaaf4056d9834bf6ae29fd81d8" Version="2.0" IssueInstant="2023-03-24T10:53:00Z" Destination="http://127.0.0.1:2222/saml2_auth/acs/" InResponseTo="id-5h2o1TDRZlfVndqll">
   <saml:Issuer>http://127.0.0.1:8080/simplesaml/saml2/idp/metadata.php</saml:Issuer>
   <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:SignedInfo>
         <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
         <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
         <ds:Reference URI="#_b215f220769ed51fbaaf4056d9834bf6ae29fd81d8">
            <ds:Transforms>
               <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
               <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <ds:DigestValue>bDBPrnSNZ/jPxalGos7RjPeY0qA=</ds:DigestValue>
         </ds:Reference>
      </ds:SignedInfo>
      <ds:SignatureValue>h5OCsmE+ojFHt0Bd0nnzZs0Al+PU08rYao0dwsLvEGEzRUl5OEh43x8byiHmbeL7Sq4QrpC7GFCiYcfCYpFO7uCPZzQCeTRC0y4w6fypI8Jip9Y0H/7U1pvuHuRkrWwlwVgaFEQ09Osx0exVzDbO3JJUvD2zkQbiC6QCe8qJNL1n/RDVBpRxda4c7TWeV6VjUFEItL1wx4QYjYOvO9yulYCVw8LAfkdtKABDNfqTe5+rPwtb+rJJ5mxtXUYjGTO5zPQ2Yi5JsT2wDcM/Tv87LKJVWgiQqnZxWqlcyyjrC/XOb7sRbQMNMgbiOI6bv5XBc3EDGq+l3pMGVavfc/ylxA==</ds:SignatureValue>
      <ds:KeyInfo>
         <ds:X509Data>
            <ds:X509Certificate>MIIDXTCCAkWgAwIBAgIJALmVVuDWu4NYMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTYxMjMxMTQzNDQ3WhcNNDgwNjI1MTQzNDQ3WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzUCFozgNb1h1M0jzNRSCjhOBnR+uVbVpaWfXYIR+AhWDdEe5ryY+CgavOg8bfLybyzFdehlYdDRgkedEB/GjG8aJw06l0qF4jDOAw0kEygWCu2mcH7XOxRt+YAH3TVHa/Hu1W3WjzkobqqqLQ8gkKWWM27fOgAZ6GieaJBN6VBSMMcPey3HWLBmc+TYJmv1dbaO2jHhKh8pfKw0W12VM8P1PIO8gv4Phu/uuJYieBWKixBEyy0lHjyixYFCR12xdh4CA47q958ZRGnnDUGFVE1QhgRacJCOZ9bd5t9mr8KLaVBYTCJo5ERE8jymab5dPqe5qKfJsCZiqWglbjUo9twIDAQABo1AwTjAdBgNVHQ4EFgQUxpuwcs/CYQOyui+r1G+3KxBNhxkwHwYDVR0jBBgwFoAUxpuwcs/CYQOyui+r1G+3KxBNhxkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAAiWUKs/2x/viNCKi3Y6blEuCtAGhzOOZ9EjrvJ8+COH3Rag3tVBWrcBZ3/uhhPq5gy9lqw4OkvEws99/5jFsX1FJ6MKBgqfuy7yh5s1YfM0ANHYczMmYpZeAcQf2CGAaVfwTTfSlzNLsF2lW/ly7yapFzlYSJLGoVE+OHEu8g5SlNACUEfkXw+5Eghh+KzlIN7R6Q7r2ixWNFBC/jWf7NKUfJyX8qIG5md1YUeT6GBW9Bm2/1/RiO24JTaYlfLdKK9TYb8sG5B+OLab2DImG99CJ25RkAcSobWNF5zD0O6lgOo3cEdB/ksCq3hmtlC/DlLZ/D8CJ+7VuZnS1rR2naQ==</ds:X509Certificate>
         </ds:X509Data>
      </ds:KeyInfo>
   </ds:Signature>
   <samlp:Status>
      <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
   </samlp:Status>
   <saml:Assertion xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="_10e7fdbb5521116726b583bceb039b1ce6005b0ec2" Version="2.0" IssueInstant="2023-03-24T10:53:00Z">
      <saml:Issuer>http://127.0.0.1:8080/simplesaml/saml2/idp/metadata.php</saml:Issuer>
      <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
         <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
            <ds:Reference URI="#_10e7fdbb5521116726b583bceb039b1ce6005b0ec2">
               <ds:Transforms>
                  <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                  <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
               </ds:Transforms>
               <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
               <ds:DigestValue>dvY3kjqtuYVkkC92P3jY/p+kUoQ=</ds:DigestValue>
            </ds:Reference>
         </ds:SignedInfo>
         <ds:SignatureValue>GjbitnduiLviwgWzltzdYJ7smABLFud/Ku0f+J1dVxj1bGkmnaTnXAQ7T6VEy1vQmVv7dhUbIyKzt3a5yJlzxq6diG+7itM6JeJ7Kz/8VrjgG0hasLjLNt3Sz+O9AkzclM6r4TWTBuz2JXjTEwmEziigqZlVqzKWWGmNBLKFkuoN6EhbC8PocbR3HeAzsSPKr5UWygKA9TYz0xSQFGvqizsh738exKe3q83GNVw1NZVsziTxDbvCWuGAx/yz82ymE09SZHsyk5AZLQ4XkBR1vfvdEYq2S6EicQebQ/v/vzn93Q5BW7sNXcj+O2uKcOybDSNZ0M6i54T2ZpwTnyqTXg==</ds:SignatureValue>
         <ds:KeyInfo>
            <ds:X509Data>
               <ds:X509Certificate>MIIDXTCCAkWgAwIBAgIJALmVVuDWu4NYMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTYxMjMxMTQzNDQ3WhcNNDgwNjI1MTQzNDQ3WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzUCFozgNb1h1M0jzNRSCjhOBnR+uVbVpaWfXYIR+AhWDdEe5ryY+CgavOg8bfLybyzFdehlYdDRgkedEB/GjG8aJw06l0qF4jDOAw0kEygWCu2mcH7XOxRt+YAH3TVHa/Hu1W3WjzkobqqqLQ8gkKWWM27fOgAZ6GieaJBN6VBSMMcPey3HWLBmc+TYJmv1dbaO2jHhKh8pfKw0W12VM8P1PIO8gv4Phu/uuJYieBWKixBEyy0lHjyixYFCR12xdh4CA47q958ZRGnnDUGFVE1QhgRacJCOZ9bd5t9mr8KLaVBYTCJo5ERE8jymab5dPqe5qKfJsCZiqWglbjUo9twIDAQABo1AwTjAdBgNVHQ4EFgQUxpuwcs/CYQOyui+r1G+3KxBNhxkwHwYDVR0jBBgwFoAUxpuwcs/CYQOyui+r1G+3KxBNhxkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAAiWUKs/2x/viNCKi3Y6blEuCtAGhzOOZ9EjrvJ8+COH3Rag3tVBWrcBZ3/uhhPq5gy9lqw4OkvEws99/5jFsX1FJ6MKBgqfuy7yh5s1YfM0ANHYczMmYpZeAcQf2CGAaVfwTTfSlzNLsF2lW/ly7yapFzlYSJLGoVE+OHEu8g5SlNACUEfkXw+5Eghh+KzlIN7R6Q7r2ixWNFBC/jWf7NKUfJyX8qIG5md1YUeT6GBW9Bm2/1/RiO24JTaYlfLdKK9TYb8sG5B+OLab2DImG99CJ25RkAcSobWNF5zD0O6lgOo3cEdB/ksCq3hmtlC/DlLZ/D8CJ+7VuZnS1rR2naQ==</ds:X509Certificate>
            </ds:X509Data>
         </ds:KeyInfo>
      </ds:Signature>
      <saml:Subject>
         <saml:NameID SPNameQualifier="http://127.0.0.1:2222/saml2_auth/acs/" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_3d1d5f33c93c8944c61a359437d793c568a9b68c84</saml:NameID>
         <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
            <saml:SubjectConfirmationData NotOnOrAfter="2023-03-24T10:58:00Z" Recipient="http://127.0.0.1:2222/saml2_auth/acs/" InResponseTo="id-5h2o1TDRZlfVndqll" />
         </saml:SubjectConfirmation>
      </saml:Subject>
      <saml:Conditions NotBefore="2023-03-24T10:52:30Z" NotOnOrAfter="2023-03-24T10:58:00Z">
         <saml:AudienceRestriction>
            <saml:Audience>http://127.0.0.1:2222/saml2_auth/acs/</saml:Audience>
         </saml:AudienceRestriction>
      </saml:Conditions>
      <saml:AuthnStatement AuthnInstant="2023-03-24T10:21:21Z" SessionNotOnOrAfter="2023-03-24T18:21:21Z" SessionIndex="_3c2f6f67375dc1d6426b0fd428a5096bd5959d21e3">
         <saml:AuthnContext>
            <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
         </saml:AuthnContext>
      </saml:AuthnStatement>
      <saml:AttributeStatement>
         <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <saml:AttributeValue xsi:type="xs:string">1</saml:AttributeValue>
         </saml:Attribute>
         <saml:Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <saml:AttributeValue xsi:type="xs:string">saml.a@incling.com</saml:AttributeValue>
         </saml:Attribute>
         <saml:Attribute Name="first_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <saml:AttributeValue xsi:type="xs:string">First A</saml:AttributeValue>
         </saml:Attribute>
         <saml:Attribute Name="last_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <saml:AttributeValue xsi:type="xs:string">Last A</saml:AttributeValue>
         </saml:Attribute>
      </saml:AttributeStatement>
   </saml:Assertion>
</samlp:Response>
rmincling commented 1 year ago

Just to add I've tried an attribute mapping file with various definitions (below) and still the same result

MAP = {
    "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:basic",
    "fro": {
        'uid': 'id',
        'email': 'email',
        'first_name': 'first_name',
        'last_name': 'last_name',
    },
    "to": {
        'id': 'uid',
        'email': 'email',
        'first_name': 'first_name',
        'last_name': 'last_name',
    }
}

and

MAP = {
    "identifier": "urn:oasis:names:tc:SAML:2.0:attrname-format:basic",
    "fro": {
        'urn:mace:dir:attribute-def:uid': 'id',
        'urn:mace:dir:attribute-def:email': 'email',
        'urn:mace:dir:attribute-def:first_name': 'first_name',
        'urn:mace:dir:attribute-def:last_name': 'last_name',
    },
    "to": {
        'id': 'urn:mace:dir:attribute-def:uid',
        'email': 'urn:mace:dir:attribute-def:email',
        'first_name': 'urn:mace:dir:attribute-def:first_name',
        'last_name': 'urn:mace:dir:attribute-def:last_name',
    }
}
rmincling commented 1 year ago

Could the issue I'm having, have anything to do with? https://djangosaml2.readthedocs.io/contents/miscellanea.html#simplesamlphp-issues If so, I'm not clear on how to fix.

But as I said above, this exact same IDP test setup works with django-saml2-auth with Django 2.22 and an older version of pysaml2 (6.5.0). Whereas now I'm using djangosaml2 with django 4.1.7 and pysaml2==7.4.1.

rmincling commented 1 year ago

Well I may as well add the solution to this. In the ['service']['sp']['endpoints'] section of my SAML_CONFIG I had this:

        'endpoints': {
              # url and binding to the assetion consumer service view
              # do not change the binding or service name
              'assertion_consumer_service': [
                  ('http://127.0.0.1:2222/saml2_auth/acs/',
                   saml2.BINDING_HTTP_REDIRECT),
              ],
          },

Not realising that I missed out defining an 'assertion_consumer_service' entry for the BINDING_HTTP_POST binding, so i changed it to this...

           'endpoints': {
              # url and binding to the assetion consumer service view
              # do not change the binding or service name
              'assertion_consumer_service': [
                  ('http://127.0.0.1:2222/saml2_auth/acs/',
                   saml2.BINDING_HTTP_REDIRECT),
                  ('http://127.0.0.1:2222/saml2_auth/acs/',
                   saml2.BINDING_HTTP_POST),
              ],
          },

This resulted in the SAML response object to detect and populate the response.ava, assertion and assertions attributes.

It's also worth noting that I did not require an attribute mapping directory/file.

peppelinux commented 1 year ago

Thank you @rmincling for have shared this!

Please feel free to add this issue in a trouble shooting section in the documentation, with a Pull Request, or any other contributions to help user in using this project

best!