def build_metadata() -> Response: """Build saml metadata.""" conf = Saml2Config() conf.load(app.config["SAML_CONFIG"]) metadata = entity_descriptor(conf) response = make_response(str(metadata).encode("utf-8")) response.headers["content-type"] = "text/xml; charset=utf-8" return response
def _get_saml_client(domain): acs_url = domain + get_reverse([acs, 'acs', 'django_saml2_auth:acs']) spConfig = Saml2Config() spConfig.load(_get_saml_client_settings(acs_url)) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) return saml_client
def s_client(self): """ Setup and return the SAML client with specified config """ acs_url = url_for('sso', _scheme='https', _external=True) logger.debug('SSO ACS URL: {}'.format(acs_url)) logout_url = url_for('logout', _scheme='https', _external=True) try: with open(self.meta_file, 'r') as meta_fh: meta_len = len(meta_fh.read()) if meta_len < 1: try: res = requests.get(self.meta_url) with open(self.meta_file, 'w') as meta_fh: meta_fh.write(res.text) ###***fix except Exception as err: logger.error( 'Invalid SAML metadata file/s provided:\n{}'.format( err)) logger.error('Invalid SAML metadata file/s provided') except FileNotFoundError as err: res = requests.get(self.meta_url) with open(self.meta_file, 'w') as meta_fh: meta_fh.write(res.text) #logger.error('Invalid SAML metadata file provided') ###***review all of these settings settings = { 'metadata': { "local": [self.meta_file] }, 'service': { 'sp': { 'name_id_format': 'None', 'endpoints': { 'assertion_consumer_service': [(acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST)], 'single_logout_service': [(logout_url, BINDING_HTTP_REDIRECT)] }, ###***update some of these if possible 'allow_unsolicited': True, #'allow_unknown_attributes': True, 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, 'attribute_map_dir': './attributemaps', }, }, } sp_config = Saml2Config() sp_config.load(settings) sp_config.entityid = self.entity_id sp_config.allow_unknown_attributes = True client = Saml2Client(config=sp_config) return client
def saml_client_for(idp_name=None): ''' Given the name of an IdP, return a configuration. The configuration is a hash for use by saml2.config.Config ''' if idp_name not in app.config['metadata_url_for']: raise Exception("Settings for IDP '{}' not found".format(idp_name)) acs_url = url_for("idp_initiated", idp_name=idp_name, _external=True, _scheme=app.config['acs_url_scheme']) # NOTE: # Ideally, this should fetch the metadata and pass it to # PySAML2 via the "inline" metadata type. # However, this method doesn't seem to work on PySAML2 v2.4.0 # # SAML metadata changes very rarely. On a production system, # this data should be cached as appropriate for your production system. rv = requests.get(app.config['metadata_url_for'][idp_name]) import tempfile tmp = tempfile.NamedTemporaryFile() f = open(tmp.name, 'w') f.write(rv.text) f.close() settings = { 'metadata': { # 'inline': metadata, "local": [tmp.name] }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST)], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } spConfig = Saml2Config() spConfig.load(settings) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) tmp.close() return saml_client
def metadata(r): acs_url = get_current_domain(r) + get_reverse([acs, 'acs', 'django_saml2_auth:acs']) saml_settings = _get_saml_client_settings(acs_url) spConfig = Saml2Config() spConfig.load(saml_settings) spConfig.allow_unknown_attributes = True metadata_string = create_metadata_string(None, config=spConfig, valid=settings.SAML2_AUTH.get('CERTIFICATES', {}).get('VALID_THROUGH', None)*24) return HttpResponse(metadata_string, content_type='text/xml')
def saml_client_for(idp_name=None): ''' Given the name of an IdP, return a configuation. The configuration is a hash for use by saml2.config.Config ''' if idp_name not in metadata_url_for: raise Exception("Settings for IDP '{}' not found".format(idp_name)) acs_url = url_for("idp_initiated", idp_name=idp_name, _external=True) https_acs_url = url_for("idp_initiated", idp_name=idp_name, _external=True, _scheme='https') # SAML metadata changes very rarely. On a production system, # this data should be cached as approprate for your production system. rv = requests.get(metadata_url_for[idp_name]) print(acs_url) BASE = "http://localhost:5000" settings = { "entityid": "%s/%ssp.xml" % (BASE, ""), 'metadata': { 'inline': [rv.text], }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST), (https_acs_url, BINDING_HTTP_REDIRECT), (https_acs_url, BINDING_HTTP_POST)], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP 'authn_requests_signed': True, 'logout_requests_signed': True, 'want_assertions_signed': False, 'want_response_signed': False, }, }, "key_file": "pki/mykey.pem", "cert_file": "pki/mycert.pem", } spConfig = Saml2Config() spConfig.load(settings) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) print("/////") print(saml_client) return saml_client
def get_saml2_client(self): saml_settings = self.get_saml2_config() sp_config = Saml2Config() sp_config.load(saml_settings) sp_config.allow_unknown_attributes = True saml_client = Saml2Client_(config=sp_config) return saml_client
def get_saml_client(): """ Return SAML configuration. The configuration is a hash for use by saml2.config.Config """ if settings.SAML_CALLBACK_SERVER_NAME: acs_url = settings.SAML_CALLBACK_SERVER_NAME + url_for("saml_auth.idp_initiated") else: acs_url = url_for("saml_auth.idp_initiated", _external=True) # NOTE: # Ideally, this should fetch the metadata and pass it to # PySAML2 via the "inline" metadata type. # However, this method doesn't seem to work on PySAML2 v2.4.0 # # SAML metadata changes very rarely. On a production system, # this data should be cached as approprate for your production system. rv = requests.get(settings.SAML_METADATA_URL) import tempfile tmp = tempfile.NamedTemporaryFile() f = open(tmp.name, 'w') f.write(rv.text) f.close() saml_settings = { 'metadata': { # 'inline': metadata, "local": [tmp.name] }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [ (acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST) ], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } spConfig = Saml2Config() spConfig.load(saml_settings) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) tmp.close() return saml_client
def saml2_sp_metadata(request, idp_name): config = Saml2Configuration.objects.get(slug=idp_name) saml_config = create_saml_config_for(config) spConfig = Saml2Config() spConfig.load(saml_config) metadata = create_metadata_string('', config=spConfig, sign=config.use_signed_authn_request) return HttpResponse(metadata, content_type="text/xml")
def saml_client_for(idp_name=None): ''' Given the name of an IdP, return a configuation. The configuration is a hash for use by saml2.config.Config ''' if idp_name not in metadata_url_for: raise Exception("Settings for IDP '{}' not found".format(idp_name)) # acs: assertion consumer service # url_for takes the view function name # http://localhost:5000/saml/sso/example-okta-com acs_url = url_for("idp_initiated", idp_name=idp_name, _external=True) # https://localhost:5000/saml/sso/example-okta-com https_acs_url = url_for("idp_initiated", idp_name=idp_name, _external=True, _scheme='https') # SAML metadata changes very rarely. On a production system, # this data should be cached as approprate for your production system. rv = requests.get(metadata_url_for[idp_name]) settings = { 'entityid': 'https://example.com/sp/metadata', 'metadata': { 'inline': [rv.text], }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(acs_url, saml2.BINDING_HTTP_REDIRECT), (acs_url, saml2.BINDING_HTTP_POST), (https_acs_url, saml2.BINDING_HTTP_REDIRECT), (https_acs_url, saml2.BINDING_HTTP_POST)], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } spConfig = Saml2Config() spConfig.load(settings) spConfig.allow_unknown_attributes = True return Saml2Client(config=spConfig)
def get_saml_client(org): """ Return SAML configuration. The configuration is a hash for use by saml2.config.Config """ metadata_url = org.get_setting("auth_saml_metadata_url") entity_id = org.get_setting("auth_saml_entity_id") if settings.SAML_SCHEME_OVERRIDE: acs_url = url_for("saml_auth.idp_initiated", org_slug=org.slug, _external=True, _scheme=settings.SAML_SCHEME_OVERRIDE) else: acs_url = url_for("saml_auth.idp_initiated", org_slug=org.slug, _external=True) saml_settings = { "metadata": { "remote": [{ "url": metadata_url }] }, "service": { "sp": { "endpoints": { "assertion_consumer_service": [ (acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST), ] }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 "allow_unsolicited": True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP "authn_requests_signed": False, "logout_requests_signed": True, "want_assertions_signed": True, "want_response_signed": False, } }, } if entity_id is not None and entity_id != "": saml_settings["entityid"] = entity_id sp_config = Saml2Config() sp_config.load(saml_settings) sp_config.allow_unknown_attributes = True saml_client = Saml2Client(config=sp_config) return saml_client
def clean(self): super().clean() cleaned_data = self.cleaned_data metadata_file = cleaned_data.get("metadata_file") if not metadata_file: return try: idp_metadata = metadata_file.read().decode("utf-8") except Exception: self.add_error("metadata_file", forms.ValidationError("Could not read SAML metadata file")) return # try to load the settings with fake entityid and acs url settings = { "metadata": { "inline": [idp_metadata], }, "entityid": "https://example.com/metadata", "service": { "sp": { "name_id_format": NAMEID_FORMAT_EMAILADDRESS, "endpoints": { "assertion_consumer_service": [ ("https://example.com/acs", BINDING_HTTP_POST), ], }, "allow_unsolicited": True, "authn_requests_signed": False, "logout_requests_signed": True, "want_assertions_signed": True, "want_response_signed": False, }, }, } sp_config = Saml2Config() sp_config.allow_unknown_attributes = True try: sp_config.load(settings) except Exception: self.add_error("metadata_file", forms.ValidationError("Invalid SAML metadata file")) # try to prepare a request # to catch errors like: # saml2.s_utils.UnsupportedBinding: urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect # when the IdP is not configured to accept redirects from Zentral try: client = Saml2Client(config=sp_config) client.prepare_for_authenticate(relay_state=str(uuid.uuid4())) except Exception as e: self.add_error("metadata_file", forms.ValidationError("{}: {}".format(e.__class__.__name__, str(e)))) else: cleaned_data["idp_metadata"] = idp_metadata return cleaned_data
def saml2_client_for(idp_name=None): ''' Given the name of an Identity Provider look up the Saml2Configuration and build a SAML Client. Return these. ''' config = Saml2Configuration.objects.get(slug=idp_name) saml_config = create_saml_config_for(config) spConfig = Saml2Config() spConfig.load(saml_config) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) return saml_client, config
def _prepare_server(self): """ Setup server """ # FIXME: remove after pysaml2 drop from saml2.config import Config as Saml2Config self.idp_config = Saml2Config() self.idp_config.load(cnf=self._config.pysaml2compat) self.server = Server(config=self.idp_config) # self._setup_app_routes()
def saml_client_for(idp_name=None): ''' This takes the idp and returns a set of configurations used by saml2.config.config ''' # This formats the settings from the xml response given by the idp for Saml2Config.load() # Using our example above, we can render the our external urls using # saml_client_for('example-okta-com') if idp_name not in metadata_url_for: raise Exception("Settings for IDP '{}' not found".format(idp_name)) acs_url = url_for("saml_auth.idp_initiated", idp_name=idp_name, _external=True) https_acs_url = url_for("saml_auth.idp_initiated", idp_name=idp_name, _external=True, _scheme='https') # SAML metadata changes very rarely. On a production system, # this data should be cached as approprate for your production system. rv = requests.get(metadata_url_for[idp_name]) settings = { 'metadata': { 'inline': [rv.text] }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST), (https_acs_url, BINDING_HTTP_REDIRECT), (https_acs_url, BINDING_HTTP_POST)], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } spConfig = Saml2Config() spConfig.load(settings) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) return saml_client
def _prepare_server(self): """ Setup server """ self.idp_config = Saml2Config() self.BASE = '{}://{}:{}'.format( self._mode, self._config.get('host'), self._config.get('port') ) if 'entityid' not in self._config: # as fallback for entityid use host:port string self._config['entityid'] = self.BASE self.idp_config.load(cnf=self._idp_config()) self.server = Server(config=self.idp_config) self._setup_app_routes()
def get_saml_client() -> Saml2Client: entityid = f"{settings.API_URL_FOR_EDUCONNECT}/saml/metadata.xml" https_acs_url = f"{settings.API_URL_FOR_EDUCONNECT}/saml/acs/" config = { "entityid": entityid, "metadata": { "local": [ path.join( BASEDIR, f"{FILES_DIR}/educonnect.{'production' if settings.IS_PROD else 'pr4'}.metadata.xml" ) ], }, "service": { "sp": { "endpoints": { "assertion_consumer_service": [(https_acs_url, BINDING_HTTP_POST)], }, "allow_unsolicited": True, "authn_requests_signed": True, "logout_requests_signed": True, "want_assertions_signed": True, "want_response_signed": True, } }, "signing_algorithm": xmldsig.SIG_RSA_SHA256, "digest_algorithm": xmldsig.DIGEST_SHA256, "cert_file": PUBLIC_CERTIFICATE_FILE_PATH, "key_file": PRIVATE_KEY_FILE_PATH, "encryption_keypairs": [{ "key_file": PRIVATE_KEY_FILE_PATH, "cert_file": PUBLIC_CERTIFICATE_FILE_PATH } # private part ], } saml2_config = Saml2Config() saml2_config.load(config) saml2_config.allow_unknown_attributes = True saml2_client = Saml2Client(config=saml2_config) return saml2_client
def saml_client_for(self, idp_name=None): ''' Given the name of an IdP, return a configuation. The configuration is a hash for use by saml2.config.Config ''' if idp_name not in self.metadata_url_for and idp_name not in self.metadata: raise Exception("Settings for IDP '{}' not found".format(idp_name)) acs_url = self.acs_format % idp_name https_acs_url = self.https_acs_format % idp_name if self.metadata_url_for: rv = requests.get(self.metadata_url_for[idp_name]) metadata = rv.text else: metadata = self.metadata[idp_name] settings = { 'entityid': 'iris', 'metadata': { 'inline': [metadata], }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [ (acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST), (https_acs_url, BINDING_HTTP_REDIRECT), (https_acs_url, BINDING_HTTP_POST) ], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': True, }, }, } spConfig = Saml2Config() spConfig.load(settings) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) return saml_client
def idp_initiated(idp_name): logging.warning("idp_name") logging.warning(idp_name) settings = idp_settings[idp_name] settings['service'] = { 'sp': { 'endpoints': { 'assertion_consumer_service': [(request.url, BINDING_HTTP_REDIRECT), (request.url, BINDING_HTTP_POST)], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, } logging.warning(settings) spConfig = Saml2Config() spConfig.load(settings) spConfig.allow_unknown_attributes = True cli = Saml2Client(config=spConfig) try: authn_response = cli.parse_authn_request_response( request.form['SAMLResponse'], entity.BINDING_HTTP_POST) authn_response.get_identity() user_info = authn_response.get_subject() username = user_info.text valid = True except Exception as e: logging.error(e) valid = False return str(e), 401 # "JIT provisioning" if username not in user_store: user_store[username] = { 'first_name': authn_response.ava['FirstName'][0], 'last_name': authn_response.ava['LastName'][0], } user = User(username) login_user(user) # TODO: If it exists, redirect to request.form['RelayState'] return redirect(url_for('user'))
def saml2_client_for(idp_name=None): ''' Given the name of an Identity Provider look up the Saml2Configuration and build a SAML Client. Return these. ''' # SAML metadata changes very rarely, check for cached version first config = Saml2Configuration.objects.get(slug=idp_name) metadata = None if config: metadata = config.cached_metadata if not metadata: r = requests.get(config.metadata_conf_url) metadata = r.text origin = getattr(settings, 'HTTP_ORIGIN').split('://')[1] https_acs_url = 'https://' + origin + reverse('assertion_consumer_service', args=[idp_name]) setting = { 'metadata': { 'inline': [metadata], }, 'entityid': "badgrserver", 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [ (https_acs_url, BINDING_HTTP_POST) ], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } spConfig = Saml2Config() spConfig.load(setting) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) return saml_client, config
def _get_saml_client(domain): acs_url = domain + get_reverse([acs, 'acs', 'django_saml2_auth:acs']) metadata = _get_metadata() authn_requests_signed = settings.SAML2_AUTH.get('AUTHN_REQUESTS_SIGNED', False) saml_settings = { 'metadata': metadata, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST)], }, 'allow_unsolicited': True, 'authn_requests_signed': authn_requests_signed, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } if 'ENTITY_ID' in settings.SAML2_AUTH: saml_settings['entityid'] = settings.SAML2_AUTH['ENTITY_ID'] if 'NAME_ID_FORMAT' in settings.SAML2_AUTH: saml_settings['service']['sp']['name_id_format'] = settings.SAML2_AUTH[ 'NAME_ID_FORMAT'] if 'ACCEPTED_TIME_DIFF' in settings.SAML2_AUTH: saml_settings['accepted_time_diff'] = settings.SAML2_AUTH[ 'ACCEPTED_TIME_DIFF'] if settings.SAML2_AUTH.get('CERT_FILE'): saml_settings['cert_file'] = settings.SAML2_AUTH['CERT_FILE'] if settings.SAML2_AUTH.get('KEY_FILE'): saml_settings['key_file'] = settings.SAML2_AUTH['KEY_FILE'] spConfig = Saml2Config() spConfig.load(saml_settings) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) return saml_client
def get_saml_client(self, handler): acs_url = self.get_current_domain(handler) + handler.reverse_url( 'saml2_acs_handler') if self.saml2_metadata_filename: metadata = {'local': [self.saml2_metadata_filename]} elif self.saml2_metadata_url: metadata = { 'remote': [ { "url": self.saml2_metadata_url, }, ] } else: raise web.HTTPError(500, 'No metadata provided') saml_settings = { 'metadata': metadata, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST)], }, 'allow_unsolicited': True, 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } if self.saml2_entity_id: saml_settings['entityid'] = self.saml2_entity_id if self.saml2_name_id_format: saml_settings['service']['sp'][ 'name_id_format'] = self.saml2_name_id_format spConfig = Saml2Config() spConfig.load(saml_settings) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) return saml_client
def get_saml_client(org): """ Return SAML configuration. The configuration is a hash for use by saml2.config.Config """ metadata_url = org.get_setting("auth_saml_metadata_url") entity_id = org.get_setting("auth_saml_entity_id") acs_url = url_for("saml_auth.idp_initiated", _external=True) saml_settings = { 'metadata': { "remote": [{ "url": metadata_url }] }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST)], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } if entity_id is not None and entity_id != "": saml_settings['entityid'] = entity_id sp_config = Saml2Config() sp_config.load(saml_settings) sp_config.allow_unknown_attributes = True saml_client = Saml2Client(config=sp_config) return saml_client
def _get_saml_client(domain): acs_url = domain + get_reverse([acs, 'acs', 'django_saml2_auth:acs']) saml_settings = { 'metadata': {}, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST)], }, 'allow_unsolicited': True, 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } if 'METADATA_AUTO_CONF_URL' in settings.SAML2_AUTH: saml_settings['metadata']['remote'] = settings.SAML2_AUTH[ 'METADATA_AUTO_CONF_URL'] if 'METADATA_AUTO_CONF_INLINE' in settings.SAML2_AUTH: saml_settings['metadata']['inline'] = settings.SAML2_AUTH[ 'METADATA_AUTO_CONF_INLINE'] if 'METADATA_AUTO_CONF_LOCAL' in settings.SAML2_AUTH: saml_settings['metadata']['local'] = settings.SAML2_AUTH[ 'METADATA_AUTO_CONF_LOCAL'] if 'ENTITY_ID' in settings.SAML2_AUTH: saml_settings['entityid'] = settings.SAML2_AUTH['ENTITY_ID'] if 'NAME_ID_FORMAT' in settings.SAML2_AUTH: saml_settings['service']['sp']['name_id_format'] = settings.SAML2_AUTH[ 'NAME_ID_FORMAT'] spConfig = Saml2Config() spConfig.load(saml_settings) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) return saml_client
def clean(self): super().clean() cleaned_data = self.cleaned_data metadata_file = cleaned_data.get("metadata_file") if not metadata_file: return try: idp_metadata = metadata_file.read().decode("utf-8") except Exception: self.add_error( "metadata_file", forms.ValidationError("Could not read SAML metadata file")) return # try to load the settings with fake entityid and acs url settings = { "metadata": { "inline": [idp_metadata], }, "entityid": "https://example.com/metadata", "service": { "sp": { "name_id_format": NAMEID_FORMAT_EMAILADDRESS, "endpoints": { "assertion_consumer_service": [ ("https://example.com/acs", BINDING_HTTP_POST), ], }, "allow_unsolicited": True, "authn_requests_signed": False, "logout_requests_signed": True, "want_assertions_signed": True, "want_response_signed": False, }, }, } sp_config = Saml2Config() sp_config.allow_unknown_attributes = True try: sp_config.load(settings) except Exception: self.add_error("metadata_file", forms.ValidationError("Invalid SAML metadata file")) else: cleaned_data["idp_metadata"] = idp_metadata return cleaned_data
async def saml_client(kind='admin'): if kind == 'admin': url = SAML_METADATA_URL_ADMIN acs_url = SAML_ACS_URL_ADMIN entity_id = SAML_ENTITY_ID_ADMIN else: url = SAML_METADATA_URL_FILER acs_url = SAML_ACS_URL_ADMIN entity_id = SAML_ENTITY_ID_FILER meta = await get_metadata(url) settings = { 'entityid': entity_id, 'metadata': { 'inline': [meta], }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [ (acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST), ], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } spConfig = Saml2Config() spConfig.load(settings) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) return saml_client
def _get_saml_client(domain): acs_url = domain + get_reverse([acs, 'acs', 'django_saml2_auth:acs']) metadata = _get_metadata() saml_settings = { 'metadata': metadata, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST)], }, 'allow_unsolicited': True, 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } if 'ENTITY_ID' in settings.SAML2_AUTH: saml_settings['entityid'] = settings.SAML2_AUTH['ENTITY_ID'] if 'NAME_ID_FORMAT' in settings.SAML2_AUTH: saml_settings['service']['sp']['name_id_format'] = settings.SAML2_AUTH[ 'NAME_ID_FORMAT'] if 'WANT_ASSERTIONS_SIGNED' in settings.SAML2_AUTH: saml_settings['service']['sp'][ 'want_assertions_signed'] = settings.SAML2_AUTH[ 'WANT_ASSERTIONS_SIGNED'] if 'WANT_RESPONSE_SIGNED' in settings.SAML2_AUTH: saml_settings['service']['sp'][ 'want_response_signed'] = settings.SAML2_AUTH[ 'WANT_RESPONSE_SIGNED'] spConfig = Saml2Config() spConfig.load(saml_settings) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) return saml_client
def _get_config_for_provider(self, base_url=None): """ Internal helper to get a configured Saml2Client """ self.ensure_one() if self.sp_baseurl: base_url = self.sp_baseurl if not base_url: base_url = (self.env["ir.config_parameter"].sudo().get_param( "web.base.url", "")) acs_url = urllib.parse.urljoin(base_url, "/auth_saml/signin") settings = { "metadata": { "inline": [self.idp_metadata] }, "entityid": self.entity_id, "service": { "sp": { "endpoints": { "assertion_consumer_service": [ (acs_url, saml2.BINDING_HTTP_REDIRECT), (acs_url, saml2.BINDING_HTTP_POST), (acs_url, saml2.BINDING_HTTP_REDIRECT), (acs_url, saml2.BINDING_HTTP_POST), ], }, "allow_unsolicited": False, "authn_requests_signed": self.sign, "logout_requests_signed": self.sign, "want_assertions_signed": self.sign, "want_response_signed": self.sign, }, }, "cert_file": self._get_cert_key_path("sp_pem_public"), "key_file": self._get_cert_key_path("sp_pem_private"), } spConfig = Saml2Config() spConfig.load(settings) spConfig.allow_unknown_attributes = True return spConfig
def saml_client_for(endpoint): """ Given the endpoint URL, return a configuration. The configuration is a hash for use by saml2.config.Config """ parts = urlparse(endpoint) # noinspection PyProtectedMember http_acs_url = urlunparse(parts._replace(scheme="http")) # noinspection PyProtectedMember https_acs_url = urlunparse(parts._replace(scheme="https")) settings = { 'entityid': 'urn:amazon:webservices', 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(http_acs_url, BINDING_HTTP_REDIRECT), (http_acs_url, BINDING_HTTP_POST), (https_acs_url, BINDING_HTTP_REDIRECT), (https_acs_url, BINDING_HTTP_POST)], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, # Although SAML response verification is disabled, pysaml2 still looks up for xmlsec1 binary. # See discussion at https://github.com/Miserlou/Zappa/issues/1374 "xmlsec_binary": "/bin/echo", } config = Saml2Config() config.load(settings) config.allow_unknown_attributes = True return Saml2Client(config=config)
def _get_saml_client(): settings = { "entityid": "http://example.com/sp/metadata.xml", 'metadata': { # 'inline': [rv.text], 'remote': [{ "url": "https://dev-386623.oktapreview.com/app/exkhvr0claqOt5UGb0h7/sso/saml/metadata" }] # "local": ["C:\\GitHub\\python34\\horizon_markets\\metadata.xml"], # "local": [".\\horizon_markets\\metadata.xml"] # "local": ["./Horizon2080_Production_SP_metadata.xml"] }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [("http://localhost:8000/login/callback", BINDING_HTTP_REDIRECT), ("http://localhost:8000/login/callback", BINDING_HTTP_POST) # (https_acs_url, BINDING_HTTP_REDIRECT), # (https_acs_url, BINDING_HTTP_POST) ], }, # Don't verify that the incoming requests originate from us via # the built-in cache for authn request ids in pysaml2 'allow_unsolicited': True, # Don't sign authn requests, since signed requests only make # sense in a situation where you control both the SP and IdP 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': False, }, }, } spConfig = Saml2Config() spConfig.load(settings) spConfig.allow_unknown_attributes = True saml_client = Saml2Client(config=spConfig) return saml_client