def handle_authn_request(self, saml_request, relay_state, binding, userid): self.authn_req = self.idp.parse_authn_request(saml_request, binding) _encrypt_cert = encrypt_cert_from_item(self.authn_req.message) self.binding_out, self.destination = self.idp.pick_binding( "assertion_consumer_service", bindings=None, entity_id=self.authn_req.message.issuer.text, request=self.authn_req.message) resp_args = self.idp.response_args(self.authn_req.message) AUTHN_BROKER = AuthnBroker() AUTHN_BROKER.add(authn_context_class_ref(PASSWORD), username_password_authn_dummy, 10, "http://test.idp.se") AUTHN_BROKER.get_authn_by_accr(PASSWORD) resp_args["authn"] = AUTHN_BROKER.get_authn_by_accr(PASSWORD) _resp = self.idp.create_authn_response(TestIdP.USERS[userid], userid=userid, encrypt_cert=_encrypt_cert, encrypt_assertion_self_contained=True, encrypted_advice_attributes=True, **resp_args) kwargs = {} http_args = self.idp.apply_binding(BINDING_HTTP_POST, "%s" % _resp, self.destination, relay_state, response=True, **kwargs) action, body = get_post_action_body(http_args["data"][3]) return action, urllib.urlencode(body)
def outgoing(self, response, org_response, instance): """ An authentication response has been received and now an authentication response from this server should be constructed. :param response: The Authentication response :param instance: SP instance that received the authentication response :return: response """ _idp = self.create_SamlIDP(instance.environ, instance.start_response, self.outgoing) _state = instance.sp.state[response.in_response_to] orig_authn_req, relay_state, req_args = instance.sp.state[_state] # The Subject NameID try: subject = response.get_subject() except: pass resp_args = _idp.idp.response_args(orig_authn_req) try: _authn_info = response.authn_info()[0] AUTHN_BROKER = AuthnBroker() AUTHN_BROKER.add(authn_context_class_ref(_authn_info[0]), username_password_authn_dummy, 0, self.issuer) _authn = AUTHN_BROKER.get_authn_by_accr(_authn_info[0]) #_authn = {"class_ref": _authn_info[0], "authn_auth": self.issuer} except: AUTHN_BROKER = AuthnBroker() AUTHN_BROKER.add(authn_context_class_ref(UNSPECIFIED), username_password_authn_dummy, 0, self.issuer) _authn = AUTHN_BROKER.get_authn_by_accr(UNSPECIFIED) identity = response.ava if identity is None and response.response.encrypted_assertion is not None: #Add dummy value identity = {"uid": "dummyuser"} # Will signed the response by default resp = _idp.construct_authn_response(identity, userid="dummyuser", authn=_authn, name_id=None, resp_args=resp_args, relay_state=relay_state, sign_response=True, org_resp=response, org_xml_response=org_response) return resp
def get_authn(self, req_info=None): if req_info: req_authn_context = req_info.message.requested_authn_context else: req_authn_context = PASSWORD broker = AuthnBroker() broker.add(authn_context_class_ref(req_authn_context), "") return broker.get_authn_by_accr(req_authn_context)
def handle_auth_req(self, saml_request, relay_state, binding, userid, response_binding=BINDING_HTTP_POST): """ Handles a SAML request, validates and creates a SAML response. :type saml_request: str :type relay_state: str :type binding: str :type userid: str :rtype: :param saml_request: :param relay_state: RelayState is a parameter used by some SAML protocol implementations to identify the specific resource at the resource provider in an IDP initiated single sign on scenario. :param binding: :param userid: The user identification. :return: A tuple with """ auth_req = self.parse_authn_request(saml_request, binding) binding_out, destination = self.pick_binding( 'assertion_consumer_service', bindings=[response_binding], entity_id=auth_req.message.issuer.text, request=auth_req.message) resp_args = self.response_args(auth_req.message) authn_broker = AuthnBroker() authn_broker.add(authn_context_class_ref(PASSWORD), lambda: None, 10, 'unittest_idp.xml') authn_broker.get_authn_by_accr(PASSWORD) resp_args['authn'] = authn_broker.get_authn_by_accr(PASSWORD) _resp = self.create_authn_response(self.user_db[userid], userid=userid, **resp_args) if response_binding == BINDING_HTTP_POST: saml_response = base64.b64encode(str(_resp).encode("utf-8")) resp = {"SAMLResponse": saml_response, "RelayState": relay_state} elif response_binding == BINDING_HTTP_REDIRECT: http_args = self.apply_binding(response_binding, '%s' % _resp, destination, relay_state, response=True) resp = dict(parse_qsl(urlparse(dict(http_args["headers"])["Location"]).query)) return destination, resp
def __create_authn_response(self, saml_request, relay_state, binding, userid, response_binding=BINDING_HTTP_POST): """ Handles a SAML request, validates and creates a SAML response but does not apply the binding to encode it. :type saml_request: str :type relay_state: str :type binding: str :type userid: str :rtype: tuple [string, saml2.samlp.Response] :param saml_request: :param relay_state: RelayState is a parameter used by some SAML protocol implementations to identify the specific resource at the resource provider in an IDP initiated single sign on scenario. :param binding: :param userid: The user identification. :return: A tuple containing the destination and instance of saml2.samlp.Response """ auth_req = self.parse_authn_request(saml_request, binding) binding_out, destination = self.pick_binding( 'assertion_consumer_service', bindings=[response_binding], entity_id=auth_req.message.issuer.text, request=auth_req.message) resp_args = self.response_args(auth_req.message) authn_broker = AuthnBroker() authn_broker.add(authn_context_class_ref(PASSWORD), lambda: None, 10, 'unittest_idp.xml') authn_broker.get_authn_by_accr(PASSWORD) resp_args['authn'] = authn_broker.get_authn_by_accr(PASSWORD) resp = self.create_authn_response(self.user_db[userid], userid=userid, **resp_args) return destination, resp
def __create_authn_response(self, saml_request, relay_state, binding, userid, response_binding=BINDING_HTTP_POST): """ Handles a SAML request, validates and creates a SAML response but does not apply the binding to encode it. :type saml_request: str :type relay_state: str :type binding: str :type userid: str :rtype: tuple [string, saml2.samlp.Response] :param saml_request: :param relay_state: RelayState is a parameter used by some SAML protocol implementations to identify the specific resource at the resource provider in an IDP initiated single sign on scenario. :param binding: :param userid: The user identification. :return: A tuple containing the destination and instance of saml2.samlp.Response """ auth_req = self.parse_authn_request(saml_request, binding) binding_out, destination = self.pick_binding( 'assertion_consumer_service', bindings=[response_binding], entity_id=auth_req.message.issuer.text, request=auth_req.message) resp_args = self.response_args(auth_req.message) authn_broker = AuthnBroker() authn_broker.add(authn_context_class_ref(PASSWORD), lambda: None, 10, 'unittest_idp.xml') authn_broker.get_authn_by_accr(PASSWORD) resp_args['authn'] = authn_broker.get_authn_by_accr(PASSWORD) resp = self.create_authn_response(self.user_db[userid], userid=userid, **resp_args) return destination, resp
def handle_auth_req(self, saml_request, relay_state, binding, userid): auth_req = self.parse_authn_request(saml_request, binding) binding_out, destination = self.pick_binding( 'assertion_consumer_service', entity_id=auth_req.message.issuer.text, request=auth_req.message) resp_args = self.response_args(auth_req.message) authn_broker = AuthnBroker() authn_broker.add(authn_context_class_ref(PASSWORD), lambda: None, 10, 'unittest_idp.xml') authn_broker.get_authn_by_accr(PASSWORD) resp_args['authn'] = authn_broker.get_authn_by_accr(PASSWORD) _resp = self.create_authn_response(self.user_db[userid], userid=userid, **resp_args) http_args = self.apply_binding(BINDING_HTTP_POST, '%s' % _resp, destination, relay_state, response=True) url = http_args['url'] saml_response = base64.b64encode(str(_resp).encode("utf-8")) resp = {'SAMLResponse': saml_response, 'RelayState': relay_state} return url, resp
def get(self, request, *args, **kwargs): passed_data = request.POST if request.method == 'POST' else request.GET # get sp information from the parameters try: sp_entity_id = passed_data['sp'] except KeyError as excp: return self.handle_error(request, exception=excp, status=400) try: sp_config = settings.SAML_IDP_SPCONFIG[sp_entity_id] except Exception: return self.handle_error( request, exception=ImproperlyConfigured( "No config for SP %s defined in SAML_IDP_SPCONFIG" % sp_entity_id), status=400) binding_out, destination = self.IDP.pick_binding( service="assertion_consumer_service", entity_id=sp_entity_id) processor = self.get_processor(sp_entity_id, sp_config) # Check if user has access to the service of this SP if not processor.has_access(request): return self.handle_error( request, exception=PermissionDenied( "You do not have access to this resource"), status=403) identity = self.get_identity(processor, request.user, sp_config) req_authn_context = PASSWORD AUTHN_BROKER = AuthnBroker() AUTHN_BROKER.add(authn_context_class_ref(req_authn_context), "") user_id = processor.get_user_id(request.user) # Construct SamlResponse messages try: name_id_formats = self.IDP.config.getattr( "name_id_format", "idp") or [NAMEID_FORMAT_UNSPECIFIED] name_id = NameID(format=name_id_formats[0], text=user_id) authn = AUTHN_BROKER.get_authn_by_accr(req_authn_context) sign_response = self.IDP.config.getattr("sign_response", "idp") or False sign_assertion = self.IDP.config.getattr("sign_assertion", "idp") or False authn_resp = self.IDP.create_authn_response( identity=identity, in_response_to=None, destination=destination, sp_entity_id=sp_entity_id, userid=user_id, name_id=name_id, authn=authn, sign_response=sign_response, sign_assertion=sign_assertion, **passed_data) except Exception as excp: return self.handle_error(request, exception=excp, status=500) # Return as html with self-submitting form. http_args = self.IDP.apply_binding( binding=binding_out, msg_str="%s" % authn_resp, destination=destination, relay_state=passed_data['RelayState'], response=True) return HttpResponse(http_args['data'])
def get(self, request, *args, **kwargs): binding = request.session.get('Binding', BINDING_HTTP_POST) # Parse incoming request try: req_info = self.IDP.parse_authn_request( request.session['SAMLRequest'], binding) except Exception as excp: return self.handle_error(request, exception=excp) # Signed request for HTTP-REDIRECT if "SigAlg" in request.session and "Signature" in request.session: _certs = self.IDP.metadata.certs(req_info.message.issuer.text, "any", "signing") verified_ok = False for cert in _certs: # TODO implement # if verify_redirect_signature(_info, self.IDP.sec.sec_backend, cert): # verified_ok = True # break pass if not verified_ok: return self.handle_error( request, extra_message="Message signature verification failure", status=400) # Gather response arguments try: resp_args = self.IDP.response_args(req_info.message) except (UnknownPrincipal, UnsupportedBinding) as excp: return self.handle_error(request, exception=excp, status=400) try: sp_config = settings.SAML_IDP_SPCONFIG[resp_args['sp_entity_id']] except Exception: return self.handle_error( request, exception=ImproperlyConfigured( "No config for SP %s defined in SAML_IDP_SPCONFIG" % resp_args['sp_entity_id']), status=400) processor = self.get_processor(resp_args['sp_entity_id'], sp_config) # Check if user has access to the service of this SP if not processor.has_access(request): return self.handle_error( request, exception=PermissionDenied( "You do not have access to this resource"), status=403) identity = self.get_identity(processor, request.user, sp_config) req_authn_context = req_info.message.requested_authn_context or PASSWORD AUTHN_BROKER = AuthnBroker() AUTHN_BROKER.add(authn_context_class_ref(req_authn_context), "") user_id = processor.get_user_id(request.user) # Construct SamlResponse message try: authn_resp = self.IDP.create_authn_response( identity=identity, userid=user_id, name_id=NameID(format=resp_args['name_id_policy'].format, sp_name_qualifier=resp_args['sp_entity_id'], text=user_id), authn=AUTHN_BROKER.get_authn_by_accr(req_authn_context), sign_response=self.IDP.config.getattr("sign_response", "idp") or False, sign_assertion=self.IDP.config.getattr("sign_assertion", "idp") or False, **resp_args) except Exception as excp: return self.handle_error(request, exception=excp, status=500) http_args = self.IDP.apply_binding( binding=resp_args['binding'], msg_str="%s" % authn_resp, destination=resp_args['destination'], relay_state=request.session['RelayState'], response=True) logger.debug('http args are: %s' % http_args) return self.render_response(request, processor, http_args)
def login_process(request): """ View which processes the actual SAML request and returns a self-submitting form with the SAML response. The login_required decorator ensures the user authenticates first on the IdP using 'normal' ways. """ # Construct server with config from settings dict conf = IdPConfig() conf.load(copy.deepcopy(settings.SAML_IDP_CONFIG)) IDP = Server(config=conf) # Parse incoming request try: req_info = IDP.parse_authn_request(request.session['SAMLRequest'], BINDING_HTTP_POST) except Exception as excp: return HttpResponseBadRequest(excp) # TODO this is taken from example, but no idea how this works or whats it does. Check SAML2 specification? # Signed request for HTTP-REDIRECT if "SigAlg" in request.session and "Signature" in request.session: _certs = IDP.metadata.certs(req_info.message.issuer.text, "any", "signing") verified_ok = False for cert in _certs: # TODO implement #if verify_redirect_signature(_info, IDP.sec.sec_backend, cert): # verified_ok = True # break pass if not verified_ok: return HttpResponseBadRequest( "Message signature verification failure") binding_out, destination = IDP.pick_binding( service="assertion_consumer_service", entity_id=req_info.message.issuer.text) # Gather response arguments try: resp_args = IDP.response_args(req_info.message) except (UnknownPrincipal, UnsupportedBinding) as excp: return HttpResponseServerError(excp) try: sp_config = settings.SAML_IDP_SPCONFIG[resp_args['sp_entity_id']] except Exception: raise ImproperlyConfigured( "No config for SP %s defined in SAML_IDP_SPCONFIG" % resp_args['sp_entity_id']) # Create user-specified processor or fallback to all-access base processor processor_string = sp_config.get('processor', None) if processor_string is None: processor = BaseProcessor else: processor_class = import_string(processor_string) processor = processor_class() # Check if user has access to the service of this SP if not processor.has_access(request.user): raise PermissionDenied("You do not have access to this resource") # Create Identity dict (SP-specific) sp_mapping = sp_config.get('attribute_mapping', {'username': '******'}) identity = processor.create_identity(request.user, sp_mapping) # TODO investigate how this works, because I don't get it. Specification? req_authn_context = req_info.message.requested_authn_context or PASSWORD AUTHN_BROKER = AuthnBroker() AUTHN_BROKER.add(authn_context_class_ref(req_authn_context), "") # Construct SamlResponse message try: authn_resp = IDP.create_authn_response( identity=identity, userid=request.user.username, name_id=NameID(format=resp_args['name_id_policy'].format, sp_name_qualifier=destination, text=request.user.username), authn=AUTHN_BROKER.get_authn_by_accr(req_authn_context), sign_response=IDP.config.getattr("sign_response", "idp") or False, sign_assertion=IDP.config.getattr("sign_assertion", "idp") or False, **resp_args) except Exception as excp: return HttpResponseServerError(excp) # Return as html with self-submitting form. http_args = IDP.apply_binding(binding=binding_out, msg_str="%s" % authn_resp, destination=destination, relay_state=request.session['RelayState'], response=True) logger.debug('http args are: %s' % http_args) if processor.enable_multifactor(request.user): # Store http_args in session for after multi factor is complete request.session['saml_data'] = http_args['data'] logger.debug("Redirecting to process_multi_factor") return HttpResponseRedirect(reverse('saml_multi_factor')) else: logger.debug("Performing SAML redirect") return HttpResponse(http_args['data'])
def get(self, request, *args, **kwargs): # pylint: disable=missing-function-docstring, too-many-locals, unused-argument passed_data = request.POST if request.method == 'POST' else request.GET # get sp information from the parameters try: sp_entity_id = passed_data['sp'] except KeyError as excp: return self.handle_error(request, exception=excp, status=400) try: # sp_config = SAML_IDP_SPCONFIG[sp_entity_id] sp_config = { 'processor': 'djangosaml2idp.processors.BaseProcessor', 'attribute_mapping': { # DJANGO: SAML 'username': '******', 'email': 'email', 'name': 'first_name', 'is_boss': 'is_admin', 'token': 'token', } } except Exception: # pylint: disable=broad-except return self.handle_error( request, exception=ImproperlyConfigured( "No config for SP %s defined in SAML_IDP_SPCONFIG" % sp_entity_id), status=400) binding_out, destination = self.IDP.pick_binding( service="assertion_consumer_service", entity_id=sp_entity_id) processor = self.get_processor(sp_entity_id, sp_config) # Check if user has access to the service of this SP if not processor.has_access(request): return self.handle_error( request, exception=PermissionDenied( "You do not have access to this resource"), status=403) identity = self.get_identity(processor, request.user, sp_config) req_authn_context = PASSWORD AUTHN_BROKER = AuthnBroker() # pylint: disable=invalid-name AUTHN_BROKER.add(authn_context_class_ref(req_authn_context), "") user_id = processor.get_user_id(request.user) # Construct SamlResponse messages try: name_id_formats = self.IDP.config.getattr( "name_id_format", "idp") or [NAMEID_FORMAT_UNSPECIFIED] name_id = NameID(format=name_id_formats[0], text=user_id) authn = AUTHN_BROKER.get_authn_by_accr(req_authn_context) sign_response = self.IDP.config.getattr("sign_response", "idp") or False sign_assertion = self.IDP.config.getattr("sign_assertion", "idp") or False authn_resp = self.IDP.create_authn_response( identity=identity, in_response_to=None, destination=destination, sp_entity_id=sp_entity_id, userid=user_id, name_id=name_id, authn=authn, sign_response=sign_response, sign_assertion=sign_assertion, **passed_data) except Exception as excp: # pylint: disable=broad-except return self.handle_error(request, exception=excp, status=500) # Return as html with self-submitting form. http_args = self.IDP.apply_binding( binding=binding_out, msg_str="%s" % authn_resp, destination=destination, relay_state=passed_data['RelayState'], response=True) return HttpResponse(http_args['data'])
def get(self, request, *args, **kwargs): # pylint: disable=missing-function-docstring, unused-argument, too-many-locals binding = request.session.get('Binding', BINDING_HTTP_POST) # Parse incoming request try: req_info = self.IDP.parse_authn_request( request.session['SAMLRequest'], binding) except Exception as excp: # pylint: disable=broad-except return self.handle_error(request, exception=excp) # Signed request for HTTP-REDIRECT if "SigAlg" in request.session and "Signature" in request.session: _certs = self.IDP.metadata.certs(req_info.message.issuer.text, "any", "signing") verified_ok = False for cert in _certs: # pylint: disable=unused-variable # TODO implement # if verify_redirect_signature(_info, self.IDP.sec.sec_backend, cert): # verified_ok = True # break pass if not verified_ok: return self.handle_error( request, extra_message="Message signature verification failure", status=400) # Gather response arguments try: resp_args = self.IDP.response_args(req_info.message) except (UnknownPrincipal, UnsupportedBinding) as excp: return self.handle_error(request, exception=excp, status=400) try: # sp_config = SAML_IDP_SPCONFIG[resp_args['sp_entity_id']] sp_config = { 'processor': 'djangosaml2idp.processors.BaseProcessor', 'attribute_mapping': { # DJANGO: SAML 'email': 'email', 'private_email': 'private_email', 'username': '******', 'is_staff': 'is_staff', 'is_superuser': '******', 'token': 'token', }, } except Exception: # pylint: disable=broad-except return self.handle_error( request, exception=ImproperlyConfigured( "No config for SP %s defined in SAML_IDP_SPCONFIG" % resp_args['sp_entity_id']), status=400) processor = self.get_processor(resp_args['sp_entity_id'], sp_config) # Check if user has access to the service of this SP if not processor.has_access(request): return self.handle_error( request, exception=PermissionDenied( "You do not have access to this resource"), status=403) cookie_user = self.cookie_user(request) identity = self.get_identity(processor, cookie_user, sp_config) req_authn_context = req_info.message.requested_authn_context or PASSWORD AUTHN_BROKER = AuthnBroker() # pylint: disable=invalid-name AUTHN_BROKER.add(authn_context_class_ref(req_authn_context), "") user_id = processor.get_user_id(cookie_user) # Construct SamlResponse message try: authn_resp = self.IDP.create_authn_response( identity=identity, userid=user_id, name_id=NameID(format=resp_args['name_id_policy'].format, sp_name_qualifier=resp_args['sp_entity_id'], text=user_id), authn=AUTHN_BROKER.get_authn_by_accr(req_authn_context), sign_response=self.IDP.config.getattr("sign_response", "idp") or False, sign_assertion=self.IDP.config.getattr("sign_assertion", "idp") or False, **resp_args) except Exception as excp: # pylint: disable=broad-except return self.handle_error(request, exception=excp, status=500) http_args = self.IDP.apply_binding( binding=resp_args['binding'], msg_str="%s" % authn_resp, destination=resp_args['destination'], relay_state=request.session['RelayState'], response=True) logger.debug('http args are: %s' % http_args) # pylint: disable=logging-not-lazy return self.render_response(request, processor, http_args)
def get(self, request, *args, **kwargs): # pylint: disable=missing-function-docstring, unused-argument, too-many-locals resp_args = { 'in_response_to': self.IN_RESPONSE_TO, 'sp_entity_id': self.SP_ENTITY_ID, 'name_id_policy': saml.NAMEID_FORMAT_PERSISTENT, 'binding': BINDING_HTTP_POST, 'destination': self.DESTINATION, } sp_config = { 'processor': 'djangosaml2idp.processors.BaseProcessor', 'attribute_mapping': { 'username': '******', 'token': 'token', 'aliyun_sso_roles': self.CUSTOM_CONFIG['role'], 'uid': self.CUSTOM_CONFIG['role_session_name'], 'aliyun_sso_session_duration': self.CUSTOM_CONFIG['session_duration'], }, } processor = self.get_processor(resp_args['sp_entity_id'], sp_config) # Check if user has access to the service of this SP if not processor.has_access(request): return self.handle_error( request, exception=PermissionDenied( "You do not have access to this resource"), status=403) cookie_user = self.cookie_user(request) if not cookie_user.aliyun_sso_role.is_active: # 用户的角色SSO被禁用 return self.handle_error( request, exception=PermissionDenied("Your role SSO has been disabled"), status=403) identity = self.get_identity(processor, cookie_user, sp_config) # print('identity is', identity) AUTHN_BROKER = AuthnBroker() # pylint: disable=invalid-name AUTHN_BROKER.add(authn_context_class_ref(PASSWORD), "") user_id = processor.get_user_id(cookie_user) # Construct SamlResponse message try: app = SAMLAPP.valid_objects.get( entity_id=resp_args['sp_entity_id']) _spsso_descriptor = entity_descriptor_from_string( app.xmldata).spsso_descriptor.pop() # pylint: disable=no-member authn_resp = self.IDP.create_authn_response( identity=identity, userid=user_id, name_id=NameID(format=resp_args['name_id_policy'], sp_name_qualifier=resp_args['sp_entity_id'], text=user_id), authn=AUTHN_BROKER.get_authn_by_accr(PASSWORD), sign_response=getattr(_spsso_descriptor, 'want_response_signed', '') == 'true', sign_assertion=getattr(_spsso_descriptor, 'want_assertions_signed', '') == 'true', **resp_args) except Exception as excp: # pylint: disable=broad-except return self.handle_error(request, exception=excp, status=500) # print('authn_resp is', authn_resp) http_args = self.IDP.apply_binding( binding=resp_args['binding'], msg_str="%s" % authn_resp, destination=resp_args['destination'], response=True) return HttpResponse(http_args['data'])
def get(self, request, *args, **kwargs): # Parse incoming request try: req_info = self.IDP.parse_authn_request(request.session['SAMLRequest'], BINDING_HTTP_POST) except Exception as excp: return HttpResponseBadRequest(excp) # TODO this is taken from example, but no idea how this works or whats it does. Check SAML2 specification? # Signed request for HTTP-REDIRECT if "SigAlg" in request.session and "Signature" in request.session: _certs = self.IDP.metadata.certs(req_info.message.issuer.text, "any", "signing") verified_ok = False for cert in _certs: # TODO implement #if verify_redirect_signature(_info, self.IDP.sec.sec_backend, cert): # verified_ok = True # break pass if not verified_ok: return HttpResponseBadRequest("Message signature verification failure") binding_out, destination = self.IDP.pick_binding(service="assertion_consumer_service", entity_id=req_info.message.issuer.text) # Gather response arguments try: resp_args = self.IDP.response_args(req_info.message) except (UnknownPrincipal, UnsupportedBinding) as excp: return HttpResponseServerError(excp) try: sp_config = settings.SAML_IDP_SPCONFIG[resp_args['sp_entity_id']] except Exception: raise ImproperlyConfigured("No config for SP %s defined in SAML_IDP_SPCONFIG" % resp_args['sp_entity_id']) processor = self.get_processor(sp_config) # Check if user has access to the service of this SP if not processor.has_access(request.user): raise PermissionDenied("You do not have access to this resource") identity = self.get_identity(processor, request.user, sp_config) # TODO investigate how this works, because I don't get it. Specification? req_authn_context = req_info.message.requested_authn_context or PASSWORD AUTHN_BROKER = AuthnBroker() AUTHN_BROKER.add(authn_context_class_ref(req_authn_context), "") # Construct SamlResponse message try: authn_resp = self.IDP.create_authn_response( identity=identity, userid=request.user.username, name_id=NameID(format=resp_args['name_id_policy'].format, sp_name_qualifier=destination, text=request.user.username), authn=AUTHN_BROKER.get_authn_by_accr(req_authn_context), sign_response=self.IDP.config.getattr("sign_response", "idp") or False, sign_assertion=self.IDP.config.getattr("sign_assertion", "idp") or False, **resp_args) except Exception as excp: return HttpResponseServerError(excp) http_args = self.IDP.apply_binding( binding=binding_out, msg_str="%s" % authn_resp, destination=destination, relay_state=request.session['RelayState'], response=True) logger.debug('http args are: %s' % http_args) return self.render_response(request, processor, http_args)