def disco_query(self, context, internal_req): """ Makes a request to the discovery server :type context: satosa.context.Context :type internal_req: satosa.internal_data.InternalRequest :rtype: satosa.response.SeeOther :param context: The current context :param internal_req: The request :return: Response """ state = context.state _cli = self.sp eid = _cli.config.entityid # returns list of 2-tuples disco_resp = _cli.config.getattr("endpoints", "sp")["discovery_response"] # The first value of the first tuple is the one I want ret = disco_resp[0][0] loc = _cli.create_discovery_service_request(self.discosrv, eid, **{"return": ret}) return SeeOther(loc)
def disco_query(self, context): """ Makes a request to the discovery server :type context: satosa.context.Context :type internal_req: satosa.internal.InternalData :rtype: satosa.response.SeeOther :param context: The current context :param internal_req: The request :return: Response """ endpoints = self.sp.config.getattr("endpoints", "sp") return_url = endpoints["discovery_response"][0][0] disco_url = (context.get_decoration( SAMLBackend.KEY_SAML_DISCOVERY_SERVICE_URL) or self.discosrv) disco_policy = context.get_decoration( SAMLBackend.KEY_SAML_DISCOVERY_SERVICE_POLICY) args = {"return": return_url} if disco_policy: args["policy"] = disco_policy loc = self.sp.create_discovery_service_request(disco_url, self.sp.config.entityid, **args) return SeeOther(loc)
def disco_query(self): """ Makes a request to the discovery server :type context: satosa.context.Context :type internal_req: satosa.internal.InternalData :rtype: satosa.response.SeeOther :param context: The current context :param internal_req: The request :return: Response """ return_url = self.sp.config.getattr("endpoints", "sp")["discovery_response"][0][0] loc = self.sp.create_discovery_service_request(self.discosrv, self.sp.config.entityid, **{"return": return_url}) return SeeOther(loc)
def handle_authn_response(self, context, internal_resp): auth_req = self._get_authn_request_from_state(context.state) affiliation_attribute = self.converter.from_internal( 'openid', internal_resp.attributes)['affiliation'] scope = auth_req['scope'] matching_affiliation = get_matching_affiliation( scope, affiliation_attribute) if matching_affiliation: return super().handle_authn_response( context, internal_resp, {'auth_time': internal_resp.auth_info.timestamp}) auth_error = AuthorizationErrorResponse(error='access_denied') del context.state[self.name] http_response = auth_error.request(auth_req['redirect_uri'], should_fragment_encode(auth_req)) return SeeOther(http_response)
def handle_authn_response(self, context, internal_resp): auth_req = self._get_authn_request_from_state(context.state) # User might not give us consent to release affiliation if 'affiliation' in internal_resp.attributes: affiliation_attribute = self.converter.from_internal('openid', internal_resp.attributes)['affiliation'] scope = auth_req['scope'] matching_affiliation = get_matching_affiliation(scope, affiliation_attribute) if matching_affiliation: return super().handle_authn_response(context, internal_resp, {'auth_time': internal_resp.auth_info.timestamp, 'requested_scopes': {'values': scope}}) # User's affiliation was not released or was not the one requested so return an error # If the client sent us a state parameter, we should reflect it back according to the spec if 'state' in auth_req: auth_error = AuthorizationErrorResponse(error='access_denied', state=auth_req['state']) else: auth_error = AuthorizationErrorResponse(error='access_denied') del context.state[self.name] http_response = auth_error.request(auth_req['redirect_uri'], should_fragment_encode(auth_req)) return SeeOther(http_response)
def handle_authn_response(self, context, internal_resp): auth_req = self._get_authn_request_from_state(context.state) resp_rp = auth_req.get('client_id') # User might not give us consent to release affiliation if 'affiliation' in internal_resp.attributes: affiliation_attribute = self.converter.from_internal('openid', internal_resp.attributes)['affiliation'] scope = auth_req['scope'] matching_affiliation = get_matching_affiliation(scope, affiliation_attribute) if matching_affiliation: transaction_log(context.state, self.config.get("response_exit_order", 1200), "inacademia_frontend", "response", "exit", "success", resp_rp , '', 'Responding successful validation to RP') return super().handle_authn_response(context, internal_resp, {'auth_time': parser.parse(internal_resp.auth_info.timestamp).timestamp(), 'requested_scopes': {'values': scope}}) # User's affiliation was not released or was not the one requested so return an error # If the client sent us a state parameter, we should reflect it back according to the spec transaction_log(context.state, self.config.get("response_exit_order", 1210), "inacademia_frontend", "response", "exit", "failed", resp_rp, '', ErrorDescription.REQUESTED_AFFILIATION_MISMATCH[LOG_MSG]) if 'state' in auth_req: auth_error = AuthorizationErrorResponse(error='access_denied', state=auth_req['state'], error_description=ErrorDescription.REQUESTED_AFFILIATION_MISMATCH[ ERROR_DESC]) else: auth_error = AuthorizationErrorResponse(error='access_denied', error_description=ErrorDescription.REQUESTED_AFFILIATION_MISMATCH[ ERROR_DESC]) del context.state[self.name] http_response = auth_error.request(auth_req['redirect_uri'], should_fragment_encode(auth_req)) return SeeOther(http_response)
def authn_request(self, context, entity_id, internal_req): """ Do an authorization request on idp with given entity id. This is the start of the authorization. :type context: satosa.context.Context :type entity_id: str :type internal_req: satosa.internal_data.InternalRequest :rtype: satosa.response.Response :param context: The curretn context :param entity_id: Target IDP entity id :param internal_req: The request :return: Response """ _cli = self.sp hash_type = UserIdHashType.persistent.name if "hash_type" in self.config: hash_type = self.config["hash_type"] req_args = {"name_id_policy": self.create_name_id_policy(hash_type)} state = context.state try: # Picks a binding to use for sending the Request to the IDP _binding, destination = _cli.pick_binding("single_sign_on_service", self.bindings, "idpsso", entity_id=entity_id) satosa_logging( LOGGER, logging.DEBUG, "binding: %s, destination: %s" % (_binding, destination), state) # Binding here is the response binding that is which binding the # IDP should use to return the response. acs = _cli.config.getattr("endpoints", "sp")["assertion_consumer_service"] # just pick one endp, return_binding = acs[0] req_id, req = _cli.create_authn_request(destination, binding=return_binding, **req_args) relay_state = rndstr() ht_args = _cli.apply_binding(_binding, "%s" % req, destination, relay_state=relay_state) satosa_logging(LOGGER, logging.DEBUG, "ht_args: %s" % ht_args, state) except Exception as exc: satosa_logging(LOGGER, logging.DEBUG, "Failed to construct the AuthnRequest for state", state, exc_info=True) raise SATOSAAuthenticationError( state, "Failed to construct the AuthnRequest") from exc state.add(self.state_id, relay_state) if _binding == BINDING_HTTP_REDIRECT: for param, value in ht_args["headers"]: if param == "Location": resp = SeeOther(str(value)) break else: satosa_logging(LOGGER, logging.DEBUG, "Parameter error for state", state) raise SATOSAAuthenticationError(state, "Parameter error") else: resp = Response(ht_args["data"], headers=ht_args["headers"]) return resp