Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I'm still having a problem with signing SSO communication (the same problem that was fixed in Issue #25) #207

Closed
kartzman opened this issue Sep 28, 2023 · 20 comments
Labels
no-issue-activity Stale action question Further information is requested

Comments

@kartzman
Copy link

kartzman commented Sep 28, 2023

Hi. I installed 3.11 and I'm still having the same problem as discussed in issue #25 (Certificate and Key File) that was fixed in 3.11. Here is the relevant part of the log file:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/django_saml2_auth/utils.py", line 185, in wrapper
    result = function(request)
  File "/usr/local/lib/python3.9/dist-packages/django_saml2_auth/views.py", line 276, in signin
    _, info = saml_client.prepare_for_authenticate(relay_state=next_url)  # type: ignore
  File "/usr/local/lib/python3.9/dist-packages/saml2/client.py", line 72, in prepare_for_authenticate
    reqid, negotiated_binding, info = self.prepare_for_negotiated_authenticate(
  File "/usr/local/lib/python3.9/dist-packages/saml2/client.py", line 150, in prepare_for_negotiated_authenticate
    reqid, request = self.create_authn_request(
  File "/usr/local/lib/python3.9/dist-packages/saml2/client_base.py", line 446, in create_authn_request
    msg = self._message(
  File "/usr/local/lib/python3.9/dist-packages/saml2/entity.py", line 588, in _message
    signed_req = self.sign(
  File "/usr/local/lib/python3.9/dist-packages/saml2/entity.py", line 524, in sign
    return signed_instance_factory(msg, self.sec, to_sign)
  File "/usr/local/lib/python3.9/dist-packages/saml2/sigver.py", line 331, in signed_instance_factory
    signed_xml = seccont.sign_statement(signed_xml, node_name=node_name, node_id=nodeid)
  File "/usr/local/lib/python3.9/dist-packages/saml2/sigver.py", line 1673, in sign_statement
    return self.crypto.sign_statement(
  File "/usr/local/lib/python3.9/dist-packages/saml2/sigver.py", line 779, in sign_statement
    (stdout, stderr, output) = self._run_xmlsec(com_list, [tmp.name])
  File "/usr/local/lib/python3.9/dist-packages/saml2/sigver.py", line 841, in _run_xmlsec
    logger.debug("xmlsec command: %s", " ".join(com_list))
TypeError: sequence item 3: expected str instance, NoneType found

Internal Server Error: /mailman3/accounts/login/

@mostafa
Copy link
Member

mostafa commented Sep 28, 2023

Hey @kartzman,

Can you provide more information, for example the configuration you used, the hooks you defined and your app configuration on your Identity Provider? Please redact sensitive information before posting.

@kartzman
Copy link
Author

kartzman commented Oct 12, 2023

Sorry for the delay.

What are the "hooks" you are referring to? I didn't define any "hooks".

I didn't set up the app configuration on the Identity Provider (Azure). The Azure admin set it up and sent me the metadata file (/var/lib/mailman3/web/azuread.xml). Is that what you want to see? If so, can you tell me what fields are considered sensitive data so I can remove them before posting the rest of that file.

Here is the SSO configuration (hostname replaced with "FQDN"):

SAML2_AUTH = {
    'DEBUG': True,
    'METADATA_LOCAL_FILE_PATH': '/var/lib/mailman3/web/azuread.xml',
    'DEFAULT_NEXT_URL': '/mailman3/postorius/lists/',
    'CREATE_USER': False,
    'NEW_USER_PROFILE': {
        'USER_GROUPS': [],
        'ACTIVE_STATUS': True,
        'STAFF_STATUS': False,
        'SUPERUSER_STATUS': False,
    },
    'ATTRIBUTES_MAP': {
        'email': 'emailAddress',
        'username': 'SamAccountName',
        'first_name': 'givenName',
        'last_name': 'surname',
    },
    'WANT_ASSERTIONS_SIGNED': True,
    'AUTHN_REQUESTS_SIGNED': True,
    'WANT_RESPONSE_SIGNED': True,

    'ENTITY_ID': 'https://FQDN/mailman3/saml2_auth/acs/',
    'TOKEN_REQUIRED': False,
}

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': '/tmp/debug.log',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': True,
        },
        'saml2': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

@kartzman
Copy link
Author

Here is the metadata file with sensitive data removed
clean.txt

@kartzman
Copy link
Author

kartzman commented Oct 12, 2023

Some additional information about the system:
OS: Debian 11
Python: 3.9.2
Django: 2.2.2.28
django-saml2-auth: 3.11

By "hooks" do you mean the contents of the urls.py file? If so, that is below:

from django.conf.urls import include, url
from django.contrib import admin
from django.http import Http404
from django.urls import reverse_lazy
from django.views.generic import RedirectView

import django_saml2_auth.views

def not_found(request):
    raise Http404("Signups are disabled on this site.")



urlpatterns = [
    # These are the SAML2 related URLs. You can change "^saml2_auth/" regex to
    # any path you want, like "^sso/", "^sso_auth/", "^sso_login/", etc. (required)
    url(r'^saml2_auth/', include('django_saml2_auth.urls')),
    # The following line will replace the default user login with SAML2 (optional)
    # If you want to specific the after-login-redirect-URL, use parameter "?next=/the/path/you/want"
    # with this view.
    url(r'^accounts/login/$', django_saml2_auth.views.signin),

    url(r'^accounts/logout/$', django_saml2_auth.views.signout, name='logout'),
    
    url(r'^$', RedirectView.as_view(
        url=reverse_lazy('list_index'),
        permanent=True)),
    url(r'^postorius/', include('postorius.urls')),
    url(r'^hyperkitty/', include('hyperkitty.urls')),
    url(r'', include('django_mailman3.urls')),
    url(r'^accounts/signup', not_found),
    url(r'^accounts/', include('allauth.urls')),
    # Django admin
    url(r'^admin/', admin.site.urls),
]

@kartzman
Copy link
Author

I forgot to mention that there are no problems and the SSO works fine when I set all these to "False"
'WANT_ASSERTIONS_SIGNED': False,
'AUTHN_REQUESTS_SIGNED': False,
'WANT_RESPONSE_SIGNED': False,

But I get the warning message:
/usr/local/lib/python3.9/dist-packages/saml2/client_base.py:193: UserWarning: The SAML service provider accepts unsigned SAML Responses and Assertions. This configuration is insecure. Consider setting want_assertions_signed, want_response_signed or want_assertions_or_response_signed configuration options.

That is why I am trying to get it to work with the configuration set to:
'WANT_ASSERTIONS_SIGNED': True,
'AUTHN_REQUESTS_SIGNED': True,
'WANT_RESPONSE_SIGNED': True,

@mostafa
Copy link
Member

mostafa commented Oct 13, 2023

@kartzman

If you set all the *_SIGNED properties to False and it works, it means that your Azure AD SAML SSO application doesn't sign the requests. So, ask your Azure AD administrator to follow the instruction No. 13 from the k6 Cloud docs to enable signing of assertions, auth requests and responses. Then, try again and see if it works and report issues otherwise.

@kartzman
Copy link
Author

It seems to be erroring out before getting to Azure. When I run the SAML tracer and I go the home page for our site I see:
GET https://HOSTNAME/
GET https://HOSTNAME/mailman3
GET https://HOSTNAME/mailman3/postorius/lists/
GET https://HOSTNAME/mailman3/static/postorius/libs/jquery/jquery-1.11.3.min.js
GET https://HOSTNAME/mailman3/static/postorius/libs/popperjs/popper-v1.11.0.min.js
GET https://HOSTNAME/mailman3/static/postorius/libs/bootstrap/js/bootstrap.min.js
GET https://HOSTNAME/mailman3/static/django-mailman3/js/main.js
GET https://HOSTNAME/mailman3/static/postorius/js/script.js
GET https://HOSTNAME/mailman3/static/postorius/img/favicon.ico

Then when I click on "login" on the homepage, which is when the SSO is supposed to happen I get the URLs below in the SAML tracer (in red) and the error message I mentioned previously on the browser screen:
GET https://HOSTNAME/mailman3/accounts/login/?next=/mailman3/postorius/lists/
GET https://HOSTNAME/favicon.ico

With all the signing options set to FALSE I get the above URLs in the SAML tracer and then the next line is:
GET https://login.microsoftonline.com/the-entity-id-is-here/saml2?SAMLRequest=some-saml-request-stuff-is-here

That's why I think I'm not even getting to Azure.

@kartzman
Copy link
Author

I just confirmed with our Azure administrator that we already were signing (at least the assertion and as of last week everything) and still it is not working:

'Yes, that's what we did. We changed the "Signing Option" from "Sign SAML assertion" to "Sign SAML response and assertion"'

@mostafa
Copy link
Member

mostafa commented Oct 16, 2023

@kartzman
From your configuration settings, it seems you haven't passed CERT_FILE and KEY_FILE locations. Also, can you provide more logs?

@kartzman
Copy link
Author

OK. I included them and it gets further along -- I get an error from Microsoft:

Sorry, but we’re having trouble signing you in.
AADSTS90015: Requested query string is too long.
Troubleshooting details
If you contact your administrator, send this info to them.
Request Id: 4c2fe8b2-47f6-4e51-869d-ed09ee1b3300
Correlation Id: 00000000-0000-0000-0000-000000000000
Timestamp: 2023-10-16T13:14:28Z
Message: AADSTS90015: Requested query string is too long.

The Azure admin gave me this link that says the solution is to use HTTP-POST instead oif HTTP-REDIRECT:
https://learn.microsoft.com/en-us/answers/questions/31352/how-to-fix-azure-single-sign-on-error-aadsts90015
Where do I set that?

@mostafa
Copy link
Member

mostafa commented Oct 17, 2023

@kartzman

There is no need to set those, as it checks the authentication response via HTTP-POST by default here. The assertion consumer service, acs, endpoint supports both.

@kartzman
Copy link
Author

The problem is not with the response, its with the request:

'AUTHN_REQUESTS_SIGNED': True, # Require each authentication request to be signed

When WANT_ASSERTIONS_SIGNED and WANT_RESPONSES_SIGNED are True and AUTHN_REQUESTS_SIGNED is False, I don't get the error. Is the authn request sent via HTTP-REDIRECT or HTTP-POST?

@mostafa
Copy link
Member

mostafa commented Oct 19, 2023

@kartzman
Do you have xmlsec1 installed? The certificate for signing the request and verifying the response signatures are in the metadata file.

@kartzman
Copy link
Author

Yes:
$ apt list --installed |grep xmlsec
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
libxmlsec1-nss/oldstable,now 1.2.31-1 amd64 [installed,automatic]
libxmlsec1-openssl/oldstable,now 1.2.31-1 amd64 [installed,automatic]
libxmlsec1/oldstable,now 1.2.31-1 amd64 [installed,automatic]
xmlsec1/oldstable,now 1.2.31-1 amd64 [installed]

@kartzman
Copy link
Author

kartzman commented Nov 6, 2023

Hi. This was all on my test machine. On my production machine, even though I have WANT_ASSERTIONS_SIGNED and WANT_RESPONSES_SIGNED set to True and AUTHN_REQUESTS_SIGNED set to False I still get an error:
Signature Error: Signature missing for response
XML parse error: Signature missing for response
saml2.sigver.SignatureError: Signature missing for response
Internal Server Error: /mailman3/saml2_auth/acs/

These errors are showing up even though CERT_FILE and KEY_FILE are specified in the config file. Any idea what could be going wrong?

@mostafa
Copy link
Member

mostafa commented Nov 7, 2023

@kartzman
The responses are signed by the certificates present in the metadata file/URL. This means that if they are missing a signature, you possibly have an issue with your metadata file/URL.

@mostafa mostafa added the question Further information is requested label Nov 7, 2023
@kartzman
Copy link
Author

kartzman commented Nov 9, 2023

Mostafa, you are right on the mark!

I forgot we only made the configuration change last month for the test server: "We changed the "Signing Option" from "Sign SAML assertion" to "Sign SAML response and assertion"' only for the test server. I just asked him to make the same change for production and now when I have WANT_ASSERTIONS_SIGNED and WANT_RESPONSES_SIGNED set to True and AUTHN_REQUESTS_SIGNED set to False I no longer get the error.

I still am getting an error when I set AUTHN_REQUESTS_SIGNED to true. Any suggestions?

@mostafa
Copy link
Member

mostafa commented Nov 9, 2023

@kartzman

I merged the PR #216, thanks to @gregorywong, that I'll release soon. See if setting KEY_FILE and CERT_FILE can help after the release.

Copy link

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions bot added the no-issue-activity Stale action label Dec 10, 2023
Copy link

This issue was closed because it has been stalled for 5 days with no activity.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Dec 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-issue-activity Stale action question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants