Coder Social home page Coder Social logo

python3-saml's People

Contributors

aidanlister avatar akx avatar beritjanssen avatar bgaifullin avatar bmorgan21 avatar bmwiedemann avatar bzvestey avatar cclauss avatar charlescbeebe avatar daxxog avatar dependabot[bot] avatar dzanin avatar fuhrysteve avatar gkhaburzaniya-onelogin avatar guneskaan avatar jgehrcke avatar jmahoney-eab avatar kipparker avatar mtyaka avatar nosnilmot avatar not-ol-github avatar op-codento avatar palbee avatar pitbulk avatar quantus avatar samm0ss avatar thelinuxkid avatar toopy avatar up_the_irons avatar y-trobinso avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python3-saml's Issues

Include SAML extensions in AuthnRequest

I've asked this in SO but got no response, and from looking at the code I could not find the correct API.

I need to include an Extensions block in AuthnRequests, for example:

<Extensions>
  <stork:QualityAuthenticationAssuranceLevel xmlns:stork="urn:oasis:names:tc:SAML:2.0:metadata">3</stork:QualityAuthenticationAssuranceLevel>
  <fa:RequestedAttributes xmlns:fa="http://autenticacao.cartaodecidadao.pt/atributos">
    <fa:RequestedAttribute Name="http://interop.gov.pt/MDC/Cidadao/NIC" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="True" />
    <fa:RequestedAttribute Name="http://interop.gov.pt/MDC/Cidadao/NIF" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="False" />
    <fa:RequestedAttribute Name="http://interop.gov.pt/MDC/Cidadao/Foto" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="False" />
    <fa:RequestedAttribute Name="http://interop.gov.pt/MDC/Cidadao/Morada" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="False" />
  </fa:RequestedAttributes>
  <fa:FAAALevel xmlns:fa="http://autenticacao.cartaodecidadao.pt/atributos">3</fa:FAAALevel>
</Extensions>

I have the schema of these elements, for example:

 <xs:schema targetNamespace="http://autenticacao.cartaodecidadao.pt/atributos" xmlns="http://autenticacao.cartaodecidadao.pt/atributos" xmlns:xs="http://www.w3.org/2001/XMLSchema" >
  <xs:element name="FAAALevel">
     <xs:simpleType>
       <xs:restriction base="xs:integer">
          <xs:minInclusive value="1"/>
          <xs:maxInclusive value="4"/>
       </xs:restriction>
     </xs:simpleType>
  </xs:element>
</xs:schema>

Does python3-saml allow me to include these blocks in AuthnRequests?

Api to extract response ids?

What is the recommended method to detect and stop replay attacts in the IdP initiated scenario?

My initial idea was to persist all previously seen Response and Assertion ids ignore responses that contain preciously seen Response or Assertion ids. Unfortunately I've not been able to find any good way to extract these ids from the response. They seem to be added to a local variable called "verified_ids" but there is no way to access it.

OneLogin_Saml2_Utils.add_sign Removes the xmlns:xs Namespace, breaking XML schema validation

Problem

When using OneLogin_Saml2_Utils.add_sign the xmlns:xs namespace gets removed from the <Assertion/> element. I suspect this happens here: https://github.com/onelogin/python3-saml/blob/master/src/onelogin/saml2/xml_utils.py#L49

As a result, this causes a response signed by this utility to fail validation when passed to OneLogin_Saml2_Auth.process_response. Specifically, this is because the xsi:type="xs:string" is not recognized when validating the response against the AuthnResponse schema.

Solution

Don't remove the xmlns:xs namespace during the call to OneLogin_Saml2_XML.to_string method used by add_sign.

Questions about python-saml and python3-saml

Hi,

I am adding SAML SSO to a project and am evaluating python-saml and python3-saml.

So far my project is Python 2/3 compatible and I would like to keep it that way, unless I have a
strong reason to change it.

According to their respective setup.py files, python-saml is Python 2 only while python3-saml is
Python 2 and 3, so using python3-saml seems like a good solution for me.

What is the relationship between the 2 projects? It seems that python-saml is more active and more
used than python3-saml. Are features and fixes applied to the first one before getting applied to
the second one later?

For production code, can we rely on python3-saml or should we use python-saml?

I have been using the Pypi version of python3-saml, which is version 1.0.0.
That version has a bug which I am running into which is fixed in the following commit:

commit c0a2081aa167aa3b5fb99e8de9f3c4636ca88ed4
Author: Patrick Arminio <[email protected]>
Date:   Fri Jan 8 11:32:19 2016 +0100

    Made make_root, make_child and cleanup_namespaces static

diff --git a/src/onelogin/saml2/xml_utils.py b/src/onelogin/saml2/xml_utils.py
index bc7500d..f7f590b 100644
--- a/src/onelogin/saml2/xml_utils.py
+++ b/src/onelogin/saml2/xml_utils.py
@@ -27,9 +27,9 @@ class OneLogin_Saml2_XML(object):
     _unparse_etree = staticmethod(etree.tostring)

     dump = staticmethod(etree.dump)
-    make_root = etree.Element
-    make_child = etree.SubElement
-    cleanup_namespaces = etree.cleanup_namespaces
+    make_root = staticmethod(etree.Element)
+    make_child = staticmethod(etree.SubElement)
+    cleanup_namespaces = staticmethod(etree.cleanup_namespaces)

     @staticmethod
     def to_string(xml, **kwargs):

Python-saml doesn't seem to have that issue.

Is a new version of python3-saml planned to include this fix?

Thank you.

SAML Response with a duplicate attribute name

Hello,

I've been looking into why an error is thrown when an attribute element has duplicated name when in the XML spec this approach is used to for an attribute to have multiple values. I've used your online tool for validating a SAML response [0] that has an attribute element with a duplicate name and this comes back as a valid response.

After further debugging I found that the error is thrown in src/response.py in the get_attributes method. I also looked at the commit where this change took place aeb25b. The commit message indates security improvements.

I'm looking for some clarity on why this change was necessary. I understand there are things I am probably not accounting for but my main goal is a discussion on the change so I can take this back to my Identity Provider or if needed implement a fix.

Tested SAML response

       <saml:AttributeStatement>
            <saml:Attribute Name="Role">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:type="xs:string"
                                     >Employee</saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="Role">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:type="xs:string"
                                     >Matthew Owens</saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="Role">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:type="xs:string"
                                     >Users</saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="Role">
                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema"
                                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:type="xs:string"
                                     >authenticated</saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>

[0] - https://www.samltool.com/validate_xml.php

Getting error <audience_url> is not a valid audience for this Response

I have found working with this package and onelogin a bit odd at time. Day before yesterday I setup every thing properly, got everything running as well. I saved the configuration from Configuration tab in web portal. Now, when I am trying to login I am getting error saying "XYZ is not a valid audience for this Response". I mean how does it work one time and refuses to work next time with same configuration is a bit odd for me. After tweaking with settings this is how I got it to work first time. But now same set of configuration is not working anymore.

SAML Consumer URL
http://mydomain/assertion-consumer-service/

SAML Single Logout URL
http://mydomain/logout/

SAML Audience
http://mydomain/

SAML Recipient
http://mydomain/assertion-consumer-service/

Redirection URL is not always returned by `auth.process_slo`

In auth.py, the docs for the function process_slo state the following:
:returns: Redirection url

This is not the case in the processing of the SAMLResponse (lhttps://github.com/onelogin/python3-saml/blame/master/src/onelogin/saml2/auth.py#L143) part of the function (although it is in the SAMLRequest part, https://github.com/onelogin/python3-saml/blame/master/src/onelogin/saml2/auth.py#L159). This means that a RelayState can only be provided in a IdP-initiated logout.

In the readme (under Initiate SLO) the following example code is provided:

target_url = 'https://example.com'
auth.logout(return_to=target_url)

This suggests that the RelayState is actually an important part of the Service Provider initiated SLO.

An easy solution would be to add the following code at line 158:

if 'RelayState' in self.__request_data['get_data']:
    return self.redirect_to()

I would create a pull request with these changes myself, but I am not entirely sure if this is intended behaviour or if this change should indeed be made.

Missing code snippet in response.py resulting in signature verification failed

There seems to be a difference between python-saml and python3-saml in response.py:

See these two commits:
SAML-Toolkits/python-saml@3eb11bc
and
a509c88

in python-saml, there is this snippet of code, which is missing in python3-saml:

multicerts = None
if 'x509certMulti' in idp_data and 'signing' in idp_data['x509certMulti'] and idp_data['x509certMulti']['signing']:
    multicerts = idp_data['x509certMulti']['signing']

This results in a signature validation failed error because python3-saml incorrectly tries to read x509cert which is empty when there are multiple certificates.

lxml ValueError exception in process_slo()

SP is using python3-saml version 1.2.6
IdP is Shibboleth Identity Provider version 3.3.0

When calling process_slo() the following exception is thrown:

    logout_response = OneLogin_Saml2_Logout_Response(self.__settings, get_data['SAMLResponse'])
  File "/opt/env/lib/python3.6/site-packages/onelogin/saml2/logout_response.py", line 41, in __init__
    self.document = OneLogin_Saml2_XML.to_etree(self.__logout_response)
  File "/opt/env/lib/python3.6/site-packages/onelogin/saml2/xml_utils.py", line 66, in to_etree
    return OneLogin_Saml2_XML._parse_etree(xml)
  File "/opt/env/lib/python3.6/site-packages/defusedxml/lxml.py", line 143, in fromstring
    rootelement = _etree.fromstring(text, parser, base_url=base_url)
  File "src/lxml/lxml.etree.pyx", line 3228, in lxml.etree.fromstring (src/lxml/lxml.etree.c:79609)
  File "src/lxml/parser.pxi", line 1843, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:119069)
ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.

As the exception says the SLO SAMLResponse contain an encoding tag, i.e. <?xml version="1.0" encoding="UTF-8"?> which isn't allowed when feeding etree.fromstring with a unicode string.

Not sure what the best solution would be in this case, but changing compat.to_string()
to compat.to_bytes() seem to work:
https://github.com/onelogin/python3-saml/blob/16cd67c0efa329ac016abdb8471cb0d654a68825/src/onelogin/saml2/logout_response.py#L40

Validation errors not shown

Hello!

For some reason the validation errors of the response here, are not shown. I only get a list with a single "invalid response" message.

I am trying to guess, that it is due to the fact, that during the validation all the error messages are assigned to the response object, (i.e. response.__errors) but the self.__errors does not get the actual validation errors from the response object.

It would be nice to fix it, since this kind of debugging takes lots of time. I need to use pdb to find out the exact validation error.

Thank you.

Server port is not always reliable under django and nginx

Hi everyone. I've been having an issue with the redirect url, my setup is more or less this one (I'm using docker, but this is not related to it):

  1. docker container with the backend running under uwsgi
  2. docker container with nginx acting as a server proxy to the first container

The nginx container uses the default port 80 meanwhile the uwsgi is using the port 8000.

Here is the function that creates the redirect url: https://github.com/onelogin/python3-saml/blob/master/src/onelogin/saml2/utils.py#L226

I can see that it is using the server_port value, which can be wrong sometimes, like in this case.

Django 1.9 has a get_port function which takes care of the specific settings https://github.com/django/django/blob/6f1318734f0f3b6e62b782b0251a4e676e542e0b/django/http/request.py#L112

I'm not sure if this can be fixed via a nginx configuration, I've tried a couple of times with no luck.

I'm happy to submit a PR but I need some guidance on the project since I'm fairly new to it :)

Running cert validation tests segfaults

All of the relevant information should be there:

vagrant@dev:/vagrant/python3-saml$ sudo apt-get update
vagrant@dev:/vagrant/python3-saml$ sudo apt-get upgrade
vagrant@dev:/vagrant/python3-saml$ sudo apt-get install libxml2-dev libxslt1-dev pkg-config libxmlsec1-dev gdb git
vagrant@dev:/vagrant/python3-saml$ sudo pip install xmlsec
vagrant@dev:/vagrant/python3-saml$ sudo pip install isodate
vagrant@dev:/vagrant/python3-saml$ sudo pip install -e '.[test]'
vagrant@dev:/vagrant/python3-saml$ python setup.py test
...
testValidateSign (tests.src.OneLogin.saml2_tests.utils_test.OneLogin_Saml2_Utils_Test) ... Segmentation fault (core dumped)
vagrant@dev:/vagrant/python3-saml$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.4 LTS"
vagrant@dev:/vagrant/python3-saml$ pip -V
pip 7.0.2 from /usr/local/lib/python2.7/dist-packages/pip-7.0.2-py2.7.egg (python 2.7)
vagrant@dev:/vagrant/python3-saml$ python -V
Python 2.7.6
vagrant@dev:/vagrant/python3-saml$ gdb python
...
(gdb) run setup.py test
...
testValidateSign (tests.src.OneLogin.saml2_tests.utils_test.OneLogin_Saml2_Utils_Test) ... 
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff4dd21da in xmlSecKeyDataIdListFindByNode () from /usr/lib/libxmlsec1.so.1
(gdb) quit
A debugging session is active.

    Inferior 1 [process 18736] will be killed.

Quit anyway? (y or n) y
vagrant@dev:/vagrant/python3-saml$ pip freeze
...
isodate==0.5.4
xmlsec==0.5.0
...

Malformed XML results in a lxml.etree.XMLSyntaxError exception

After creating a OneLogin_Saml2_Auth object with a request that contains malformed XML and calling process_response(), the call will raise a lxml.etree.XMLSyntaxError exception.

This is reasonable behavior, but I think it could be improved. I think that in general, libraries should try to avoid raising exceptions that their dependencies raise. There is already a OneLogin_Saml2_Error exception that is raised in various error cases. What would you think about catching lxml.etree.Error exceptions in OneLogin_Saml2_XML and raising a OneLogin_Saml2_Error exception with a new error code for XML parse failures?

XML metadata parser does not allow for SSO POST binding extraction

Right now, the parser only extracts one SSO URL (fine), and only for the redirect binding (that's a severe limitation). We should expose a parameter to instruct the parser to either extract the first

  • SSO URL with redirect binding or the first
  • SSO URL with POST binding

IDP in python3-saml

Hi, Can I create IDP by using python3-saml. I read the documentation and could not found any related page.

Feature support: SLO ResponseLocation and NameID NameQualifier

Hi,

I need 2 features that I don't see implemented, unless I didn't find them.

a) Our IdP uses ResponseLocation in addition to Location for its SingleLogoutService.
I.E. its metadata contains:

<ns0:SingleLogoutService
  Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
  Location="https://<idp url>/idp/saml2/slo"
  ResponseLocation="https://<idp url>/idp/saml2/slo_return"  # this extra URL
/>

But it seems that using this second URL (optional in the SAML spec) isn't supported in python3-saml.

To implement it, it seems that we would need to:

  • Support the response location URL in OneLogin_Saml2_Settings.
  • Update logic in OneLogin_Saml2_Auth.process_slo in the case of SAMLResponse to use that URL when available or fall back on the current one.

b) Our IdP seems to require NameQualifier to be passed as an attribute of NameID in the LogoutRequest resulting from a logout initiated on the SP side.

<saml:NameID
    Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
    # NameQualifier missing here
>transient id
</saml:NameID>

I see that the NameQualifier is included in the login assertion, and I think we can access it and keep track of it in our session. For the rest of the implementation we would have to:

  • Modify OneLogin_Saml2_Auth.logout to accept name_qualifier and pass it to OneLogin_Saml2_Logout_Request.
  • Modify OneLogin_Saml2_Logout_Request to accept name_qualifier and pass it to OneLogin_Saml2_Utils.generate_name_id.
  • Modify OneLogin_Saml2_Utils.generate_name_id to accept name_qualifier and use it when building the XML element.

Would supporting these features fit with the project vision?
Would you implement them, or accept pull requests matching the high level implementations described above?

Thank you.
Pierre

Undocumented "req" Parameters

There are 3 undocumented parameters that could potentially be passed as part the req dict used to initialize the OneLogin_Saml2_Auth client. These are:

  1. https - Unsuspecting users could potentially see validation of responses fail if they're received over HTTPS and the user didn't explicitly configure that (since the default is http)

  2. lowercase_urlencoding - There's a short comment in utils.py describing why this is an option, but users may not be aware of this option if they're using ADFS

  3. request_uri - Used in utils.py#L339-L380 to build self URLs

In the documentation users should at least be aware of these options, what they're for, and when they should be used. Ideally no one should have to read your source code to use your client. ๐Ÿ™‚

Reply address is empty, Azure AD SAML application

Hi I'm playing with flask demo and I still receive this error.

AADSTS50011: Reply address '' specified by the request is not a valid URL. Allowed schemes: 'http,https,ms-app'

Could you please tell me where to start debugging?
I got successful redirect to signin page but then the error.

my config in AAD:

"replyUrls": [
"https://localhost:9876/callback"
],

Let me know if you need more.

Authentication failed: SAML login failed: ['invalid_response']

The response URL is adding a port number to the URL.

(The response was received at https://www.site.com:80/complete/saml/ instead of https://www.site.com/complete/saml/)

I am connecting to a ADFS Server. Is this a SP issue? or a IDP setting issue?

win7 python3-saml install error

How to solve this problem for Very anxiousใ€‚thank you
LINK : fatal error LNK1159: no output file specified
error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.13.26128\bin\HostX86\x64\link.exe' failed with exit status 1159

serviceName and serviceDescription are not xml-escaped

When building metadata XML from config dict, the keys serviceName and serviceDescription are included using %s in XML string concatenation.

If they contain for example & they will generate a malformed XML document and libxml2 will error out.

They should be xml encoded before being included in the resulting xml document.

This might affect also other values ?

Note: This can introduce a breaking change if people noticed that, and provide an xml-encoded value in serviceName and serviceDescription, resulting in a double encoding.

There is no AttributeStatement on the Response

Is it necessary to require an Attribute Statement in the SAML Response?

When setting up a SAML app in Okta (the Identity Provider in this case), the form says that configuring Attribute Statements is optional. That leaves us open to the above error though. I've also run into this issue when using Centrify as an IdP.

So would it be possible to remove this check and what would be the implications of that? Thanks for the help!

Reference: Check out the Attribute Statements section in step 7
http://developer.okta.com/docs/guides/setting_up_a_saml_application_in_okta.html

Impossible to catch exceptions that aren't OneLogin_Saml2_Error

I'm having an issue where the library is throwing an Exception that is of the base Exception type. I want to handle errors gracefully that occur within this library, but don't really want to catch every single exception that occurs.

Is there a particular reason this library uses OneLogin_Saml2_Error in some places, but others, like in https://github.com/onelogin/python3-saml/blob/master/src/onelogin/saml2/response.py#L301, just use Exception? Would it be possible to introduce a new class of Exception which is used in place of these so that they can be caught more easily without catching all Exception types.

Cheers

"All Rights Reserved"

The LICENSE file claims MIT, however all the source files include the following:

Copyright (c) 2014, OneLogin, Inc.
All rights reserved.

Please update the source file headers to include the license text, and not say "All rights reserved" to clarify. The year should likely be updated as well to include all the years in which code was committed (and thus published) under this copyright.

This same issue also affects python-saml tree.

RelayState Should Not Be Required in Request

According to the SAML Profile for Single Sign-On AuthnRequests, the Service Provider MAY send a RelayState along with the request, but that it's not required. See section 4.1.3.1 of this document:
https://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf

However, in OneLogin_Saml2_Auth.login() (in auth.py) this parameter is always set, even if return_to is a blank string. For example, a redirect_url returned by login() could look like:

http://acme.onelogin.com/saml/login?SAMLRequest=<b64_encoded_req>&RelayState=

This could potentially be misleading for Identity Providers that detect the RelayState parameter in the request only to discover that it's blank.

I propose that the RelayState parameter should not be set at all if return_to is None, or an empty string (''). If you think that's a reasonable fix, I'll create a PR for you. ๐Ÿ™‚

Single Logout Service never called

Hi,

When I log out of my Django application that is a service provider, I am correctly redirected to the logout page of the IDP that I am using (Salesforce in this case). However, when I then navigate back to my site (i.e. the service provider), I am not presented with the login page, but instead it seems like I'm already logged in. I then figured out that my singleLogoutService url is never being hit, and so auth.process_slo() is never being executed (so my session is not being deleted). Do you know what could be causing this?

Thanks.

IdPMetadataParser.merge_settings() does a shallow merge

The current merger uses Python's dict update() method which operates only on the first hierarchy level, it does not do a deep merge of nested dictionaries. This mode of operation is insufficient for the settings merger (i.e. it does not fulfill what's currently documented: "Will update the settings with the provided new settings data extracted from the IdP metadata").

HTTP_X_FORWARDED

Hi Onelogin team,

I'm attempting to run the demo-flask code however my application is configured behind nginx to allow for encryption over https. In the source code there is a note on HTTP_X_FORWARDED fields, and I don't believe I have these configured. I've tried searching to see if there was additional information but found nothing on github. Could you provide more information on this note? How would I change the configuration of the app and/or nginx to accomplish this?

I've created print() calls to help with troubleshooting. It looks like the application believes the protocol is http on port 443 instead of using https.

def prepare_flask_request(request):
    # If server is behind proxys or balancers use the HTTP_X_FORWARDED fields
    url_data = urlparse(request.url)
    print (request.url)
    print (url_data)

OUTPUT FROM LOG FILES: 
http://example.com:443/?acs
ParseResult(scheme='http', netloc='example.com:443', path='/', params='', query='acs', fragment='')

Better instructions for Heroku

It's a serious pain getting this package up and running on Heroku!

This seems like it should work, but I get fatal error: xmlsec/xmltree.h: No such file or directory

As a fabfile.py for reproducability:

@task
def configure_as_build_server(app):
    local('heroku buildpacks:set --index=1 -a {app} https://github.com/ddollar/heroku-buildpack-apt'.format(app=app))
    local('heroku buildpacks:set --index=2 -a {app} https://github.com/heroku/heroku-buildpack-python'.format(app=app))

With the following Aptfile:

libxml2-dev
libxmlsec1-dev

Could there be some documentation added?

Local ADFS Server Settings

Does any one have any info as to the setting i need to put in the settings file to point Python SAML at a local adfs server?

The status code of the Response was not Success, was Responder

Instead of a "Success" status after login with ADFS, we're getting the following error: "The status code of the Response was not Success, was Responder". In the python-saml project issues, someone had this same issue and it was caused by requestedAuthnContext being set to true in advanced_settings. I have set it to false, yet I still get this error. Are there any more settings I should check in my app before asking the IDP ADFS person to check their logs?

Thanks.

How to fix destination validation?

Hello!

I am using your python3-saml module and I have some misunderstanding with ports, when implementing SAML2 SSO for our app. The validation of the destination fails because there is a validation of the current_url here and it constructs that url in utils. But for some reason the port in the current_url is not default, but 8080.

I understand, that this port is extracted from our side, but this does not have much sense, since the request itself is made on the default url https://example.com/sso/saml2/?acs, but our IDP must have ACS url with port 8080 in his SAMLResponse https://example.com:8080/sso/saml2/?acs to be able to pass this validation.

So, I have a misunderstanding here. What exactly this validation checks? Is it possible to disable it and do I increase the security risk in this case?

Thank you.

IdP-initiated SLO does not work with Python3

SLO does not function properly. Probably only affects Python3.

Symptoms:

calling OneLogin_Saml2_Auth.process_slo() leads to:

  • in the log: invalid_logout_request
  • defusedxml writes into stdout: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.

Cause

logout_request.py:115:

self.__logout_request = compat.to_string(logout_request)

Afterwards python3-saml in OneLogin_Saml2_XML.to_etree() calls defusedxml.lxml.fromstring with text argument containing a str instance (unicode in Python3), which causes the error.

Notes:

defusedxml.lxml.fromstring is actually called twice during OneLogin_Saml2_Auth.process_slo().

  • First time while extracting ID of the request as far as I can remember. It passes correct arguments to defusedxml.lxml.fromstring.
  • Second time while validating the request. This time with invalid arguments which causes defusedxml to fail.

Possible solution:

Replacing in logout_request.py:115

self.__logout_request = compat.to_string(logout_request)

with

self.__logout_request = logout_request

solves the problem and makes SLO to function.

I am however not sure why compat.to_string() was used and which side effects removing it might cause.

Versions

python3-saml==1.3.0
defusedxml==0.5.0
lxml==4.1.1
xmlsec==1.3.3

One response test doesn't behave in a reasonable way

While writing PR #37 I noticed that the test testOnlyRetrieveAssertionWithIDThatMatchesSignatureReference behaves in a really odd way. The self.assertTrue(response.is_valid(self.get_request_data())) line raises an AssertionException that moves the execution to the line self.assertEqual(.... That leaves these lines that never get executed. The test function comment says that the function should tests get_nameid function, but it doesn't even get called during that test.

I would except that each test have just one execution path that can lead to test passing, but that is not the case with this tests. I don't feel like I understand this test enough to offer a fix for this test case.

auth.get_session_expiration()

I'm trying to retrieve the NotOnOrAfter value from the response using the get_session_expiration() inside of auth.py. The only thing done here was I've added this request to the Flask index.py right after receiving the attributes, name_id and session_index to demonstrate this problem.

    elif 'acs' in request.args:
        auth.process_response()
        errors = auth.get_errors()
        not_auth_warn = not auth.is_authenticated()
        if len(errors) == 0:
            session['samlUserdata'] = auth.get_attributes()
            session['samlNameId'] = auth.get_nameid()
            session['samlSessionIndex'] = auth.get_session_index()
            session['samlSessionExpiration'] = auth.get_session_expiration()

The variable session['samlSessionExpiration'] returns None instead of the date/time. I know this works within the response.py as it is used to authenticate the IdP response. Why would this return "None" instead of the date in the auth.py?

XML metadata parser does not expose binding type

The metadata parser does not set the binding key in the singleSignOnService dictionary, it only stores the url key. A settings consumer cannot guess which binding is to be used, so we need to add the binding.

Extracting session index from logout request

When handling a logout request, there doesn't seem to be a simple way to extract/obtain the session index from a logout request.

Is there such an API available to obtain this information?

Doing auth.get_session_index() returns None.

ImportError: lxml.etree does not export expected C function adoptExternalDocument

Encountered this issue when running this library within a Linux environment/container (python:3.6-slim):

app_1  | + python3 manage.py migrate
app_1  | Traceback (most recent call last):
app_1  |   File "manage.py", line 22, in <module>
app_1  |     execute_from_command_line(sys.argv)
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/management/__init__.py", line 363, in execute_from_command_line
app_1  |     utility.execute()
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/management/__init__.py", line 355, in execute
app_1  |     self.fetch_command(subcommand).run_from_argv(self.argv)
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
app_1  |     self.execute(*args, **cmd_options)
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 327, in execute
app_1  |     self.check()
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 359, in check
app_1  |     include_deployment_checks=include_deployment_checks,
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 62, in _run_checks
app_1  |     issues.extend(super(Command, self)._run_checks(**kwargs))
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 346, in _run_checks
app_1  |     return checks.run_checks(**kwargs)
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/checks/registry.py", line 81, in run_checks
app_1  |     new_errors = check(app_configs=app_configs)
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/checks/urls.py", line 16, in check_url_config
app_1  |     return check_resolver(resolver)
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/core/checks/urls.py", line 26, in check_resolver
app_1  |     return check_method()
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/urls/resolvers.py", line 254, in check
app_1  |     for pattern in self.url_patterns:
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
app_1  |     res = instance.__dict__[self.name] = self.func(instance)
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/urls/resolvers.py", line 405, in url_patterns
app_1  |     patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
app_1  |     res = instance.__dict__[self.name] = self.func(instance)
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/urls/resolvers.py", line 398, in urlconf_module
app_1  |     return import_module(self.urlconf_name)
app_1  |   File "/usr/local/lib/python3.6/importlib/__init__.py", line 126, in import_module
app_1  |     return _bootstrap._gcd_import(name[level:], package, level)
app_1  |   File "<frozen importlib._bootstrap>", line 994, in _gcd_import
app_1  |   File "<frozen importlib._bootstrap>", line 971, in _find_and_load
app_1  |   File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
app_1  |   File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
app_1  |   File "<frozen importlib._bootstrap_external>", line 678, in exec_module
app_1  |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
app_1  |   File "/app/customer_success_site/urls.py", line 23, in <module>
app_1  |     url(r'', include('tools.urls')),
app_1  |   File "/usr/local/lib/python3.6/site-packages/django/conf/urls/__init__.py", line 50, in include
app_1  |     urlconf_module = import_module(urlconf_module)
app_1  |   File "/usr/local/lib/python3.6/importlib/__init__.py", line 126, in import_module
app_1  |     return _bootstrap._gcd_import(name[level:], package, level)
app_1  |   File "<frozen importlib._bootstrap>", line 994, in _gcd_import
app_1  |   File "<frozen importlib._bootstrap>", line 971, in _find_and_load
app_1  |   File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
app_1  |   File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
app_1  |   File "<frozen importlib._bootstrap_external>", line 678, in exec_module
app_1  |   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
app_1  |   File "/app/tools/urls.py", line 2, in <module>
app_1  |     from . import views
app_1  |   File "/app/tools/views.py", line 19, in <module>
app_1  |     from .saml import init_saml_auth, prepare_django_request
app_1  |   File "/app/tools/saml.py", line 4, in <module>
app_1  |     from onelogin.saml2.auth import OneLogin_Saml2_Auth
app_1  |   File "/usr/local/lib/python3.6/site-packages/onelogin/saml2/auth.py", line 14, in <module>
app_1  |     import xmlsec
app_1  | ImportError: lxml.etree does not export expected C function adoptExternalDocument

Not sure what's the issue here, but noticed that it uninstalled lxml 4.1.1 when I tried pip install:

Installing collected packages: beautifulsoup4, pytz, Django, gunicorn, htmlmin, lxml, mysqlclient, numpy, six, python-dateutil, pandas, psycopg2, rcssmin, requests, rjsmin, SQLAlchemy, xlrd, XlsxWriter, ujson, MarkupSafe, Jinja2, isodate, defusedxml, python3-saml
  Found existing installation: lxml 4.1.1
    Uninstalling lxml-4.1.1:
      Successfully uninstalled lxml-4.1.1
Successfully installed Django-1.11 Jinja2-2.9.6 MarkupSafe-1.0 SQLAlchemy-1.1.9 XlsxWriter-0.9.8 beautifulsoup4-4.6.0 defusedxml-0.5.0 gunicorn-19.7.1 htmlmin-0.1.10 isodate-0.6.0 lxml-3.7.3 mysqlclient-1.3.10 numpy-1.12.1 pandas-0.21.0 psycopg2-2.7.1 python-dateutil-2.6.0 python3-saml-1.3.0 pytz-2017.2 rcssmin-1.0.6 requests-2.14.2 rjsmin-1.0.12 six-1.10.0 ujson-1.35 xlrd-1.0.0

csrf django issue

We have csrf middelware enabeled.
It appears it's not happy with the saml request.

Error:
CSRF token missing or incorrect is the error in django

How can this be fixed?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.