Пример #1
0
 def _create_saml_auth(self, idp):
     """Get an instance of OneLogin_Saml2_Auth"""
     config = self.generate_saml_config(idp)
     request_info = {
         'https': 'on' if self.strategy.request_is_secure() else 'off',
         'http_host': self.strategy.request_host(),
         'script_name': self.strategy.request_path(),
         'server_port': self.strategy.request_port(),
         'get_data': self.strategy.request_get(),
         'post_data': self.strategy.request_post(),
     }
     return OneLogin_Saml2_Auth(request_info, config)
Пример #2
0
async def load_login_config(request: Request) -> LoginConfiguration:
	if ask_sso_enabled() and ask_saml2_enabled():
		from watchmen_rest_doll.sso.saml.saml_helper import prepare_from_fastapi_request
		# noinspection PyPackageRequirements
		from onelogin.saml2.auth import OneLogin_Saml2_Auth

		req = await prepare_from_fastapi_request(request)
		auth = OneLogin_Saml2_Auth(req, ask_saml2_settings())
		callback_url = auth.login()
		return LoginConfiguration(method=SSOTypes.SAML2, url=callback_url)
	else:
		return LoginConfiguration(method=SSOTypes.DOLL)
Пример #3
0
 def render_GET(self, request):
     request.setHeader(b"content-type", b"text/plain")
     req = self._prepare_from_twisted_request(request)
     auth = OneLogin_Saml2_Auth(req, old_settings=self.settings)
     saml_settings = auth.get_settings()
     metadata = saml_settings.get_sp_metadata()
     errors = saml_settings.validate_metadata(metadata)
     if len(errors) == 0:
         content = metadata
     else:
         content = "Error found on Metadata: %s" % (', '.join(errors))
     return content.encode("ascii")
Пример #4
0
    def POST(self):
        SAML_PATH = config_get('saml', 'config_path')
        request = ctx.env
        data = dict(param_input())
        req = prepare_webpy_request(request, data)
        auth = OneLogin_Saml2_Auth(req, custom_base_path=SAML_PATH)

        auth.process_response()
        errors = auth.get_errors()
        if not errors:
            if auth.is_authenticated():
                setcookie('saml-nameid', value=auth.get_nameid(), path='/')
def metadata():
    auth = OneLogin_Saml2_Auth(prepare_saml_request(request),
                               current_app.config["SAML"])
    metadata = auth.get_settings().get_sp_metadata()
    errors = auth.get_settings().validate_metadata(metadata)

    if len(errors) == 0:
        resp = make_response(metadata, 200)
        resp.headers['Content-Type'] = 'text/xml'
    else:
        resp = make_response(', '.join(errors), 500)
    return resp
Пример #6
0
    def GET(self, id):
        settings = self.user_manager.get_auth_method(id).get_settings()
        auth = OneLogin_Saml2_Auth(prepare_request(settings), settings)
        metadata = auth.get_settings().get_sp_metadata()
        errors = auth.get_settings().validate_metadata(metadata)

        if len(errors) == 0:
            web.header('Content-Type', 'text/xml')
            return metadata
        else:
            web.ctx.status = "500 Internal Server Error"
            return ', '.join(errors)
Пример #7
0
    def GET(self):
        global settings
        auth = OneLogin_Saml2_Auth(prepare_request(), settings)
        metadata = auth.get_settings().get_sp_metadata()
        errors = auth.get_settings().validate_metadata(metadata)

        if len(errors) == 0:
            web.header('Content-Type', 'text/xml')
            return metadata
        else:
            web.ctx.status = "500 Internal Server Error"
            return ', '.join(errors)
Пример #8
0
def logout(request, **kwargs):
    idp = get_request_idp(request, **kwargs)
    redir = idp.get_logout_redirect(request.GET.get(REDIRECT_FIELD_NAME))
    saml = OneLogin_Saml2_Auth(idp.prepare_request(request),
                               old_settings=idp.settings)
    if saml.get_slo_url() and idp.logout_triggers_slo:
        # If the IdP supports SLO, send it a logout request (it will call our SLO).
        return redirect(saml.logout(redir))
    else:
        # Handle the logout "locally", i.e. log out via django.contrib.auth by default.
        idp.logout(request)
        return redirect(redir)
Пример #9
0
    def testGetSessionIndex(self):
        """
        Tests the get_session_index method of the OneLogin_Saml2_Auth class
        """
        settings_info = self.loadSettingsJSON()
        auth = OneLogin_Saml2_Auth(self.get_request(),
                                   old_settings=settings_info)
        self.assertIsNone(auth.get_session_index())

        request_data = self.get_request()
        message = self.file_contents(
            join(self.data_path, 'responses', 'valid_response.xml.base64'))
        del request_data['get_data']
        request_data['post_data'] = {'SAMLResponse': message}
        auth2 = OneLogin_Saml2_Auth(request_data,
                                    old_settings=self.loadSettingsJSON())
        self.assertIsNone(auth2.get_session_index())

        auth2.process_response()
        self.assertEqual('_6273d77b8cde0c333ec79d22a9fa0003b9fe2d75cb',
                         auth2.get_session_index())
Пример #10
0
    def init_saml_auth(req, config):
        """Prepare SAML request

        :param req: :class:`microkubes.security.chain.Request`, wrapped HTTP Request.

        :param config: ``dict``, SAML config

        :returns: an instance of OneLogin_Saml2_Auth
        """

        settingsSAML = OneLogin_Saml2_Settings(settings=config)
        auth = OneLogin_Saml2_Auth(req, old_settings=settingsSAML)
        return auth
Пример #11
0
    def testProcessNoResponse(self):
        """
        Tests the process_response method of the OneLogin_Saml2_Auth class
        Case No Response, An exception is throw
        """
        auth = OneLogin_Saml2_Auth(self.get_request(),
                                   old_settings=self.loadSettingsJSON())

        with self.assertRaisesRegexp(OneLogin_Saml2_Error,
                                     'SAML Response not found'):
            auth.process_response()

        self.assertEqual(auth.get_errors(), ['invalid_binding'])
Пример #12
0
 def testProcessNoSLO(self):
     """
     Tests the process_slo method of the OneLogin_Saml2_Auth class
     Case No Message, An exception is throw
     """
     auth = OneLogin_Saml2_Auth(self.get_request(),
                                old_settings=self.loadSettingsJSON())
     try:
         auth.process_slo(True)
     except Exception as e:
         self.assertIn('SAML LogoutRequest/LogoutResponse not found',
                       e.message)
     self.assertEqual(auth.get_errors(), ['invalid_binding'])
Пример #13
0
 async def saml_login(request: Request):
     req = await prepare_saml_from_fastapi_request(request)
     auth = OneLogin_Saml2_Auth(req, self.saml_settings)
     # saml_settings = auth.get_settings()
     # metadata = saml_settings.get_sp_metadata()
     # errors = saml_settings.validate_metadata(metadata)
     # if len(errors) == 0:
     #   print(metadata)
     # else:
     #   print("Error found on Metadata: %s" % (', '.join(errors)))
     callback_url = auth.login()
     response = RedirectResponse(url=callback_url)
     return response
Пример #14
0
def init_saml_auth(
        request, provider_key: str) -> Tuple[OneLogin_Saml2_Auth, dict, dict]:
    """
    Gets the SAML provider settings and returns a prepared SAML request and OneLogin Auth object
    """
    saml_req = prepare_django_request(request)
    provider_settings, user_map = get_provider_settings(saml_req, provider_key)
    saml_req["lowercase_urlencoding"] = provider_settings.get(
        "lowercase_urlencoding", False)
    saml_req["idp_initiated_auth"] = provider_settings.get(
        "idp_initiated_auth", True)
    auth = OneLogin_Saml2_Auth(saml_req, provider_settings)
    return auth, saml_req, user_map
Пример #15
0
    def testLoginSetNameIDPolicy(self):
        """
        Tests the login method of the OneLogin_Saml2_Auth class
        Case Logout with no parameters. A AuthN Request is built with and without NameIDPolicy
        """
        settings_info = self.loadSettingsJSON()
        return_to = u'http://example.com/returnto'
        sso_url = settings_info['idp']['singleSignOnService']['url']

        auth = OneLogin_Saml2_Auth(self.get_request(),
                                   old_settings=settings_info)
        target_url = auth.login(return_to)
        parsed_query = parse_qs(urlparse(target_url)[4])
        sso_url = settings_info['idp']['singleSignOnService']['url']
        self.assertIn(sso_url, target_url)
        self.assertIn('SAMLRequest', parsed_query)
        request = OneLogin_Saml2_Utils.decode_base64_and_inflate(
            parsed_query['SAMLRequest'][0])
        self.assertIn('<samlp:NameIDPolicy', request)

        auth_2 = OneLogin_Saml2_Auth(self.get_request(),
                                     old_settings=settings_info)
        target_url_2 = auth_2.login(return_to, False, False, True)
        parsed_query_2 = parse_qs(urlparse(target_url_2)[4])
        self.assertIn(sso_url, target_url_2)
        self.assertIn('SAMLRequest', parsed_query_2)
        request_2 = OneLogin_Saml2_Utils.decode_base64_and_inflate(
            parsed_query_2['SAMLRequest'][0])
        self.assertIn('<samlp:NameIDPolicy', request_2)

        auth_3 = OneLogin_Saml2_Auth(self.get_request(),
                                     old_settings=settings_info)
        target_url_3 = auth_3.login(return_to, False, False, False)
        parsed_query_3 = parse_qs(urlparse(target_url_3)[4])
        self.assertIn(sso_url, target_url_3)
        self.assertIn('SAMLRequest', parsed_query_3)
        request_3 = OneLogin_Saml2_Utils.decode_base64_and_inflate(
            parsed_query_3['SAMLRequest'][0])
        self.assertNotIn('<samlp:NameIDPolicy', request_3)
Пример #16
0
 def testRedirectTo(self):
     """
     Tests the redirect_to method of the OneLogin_Saml2_Auth class
     (phpunit raises an exception when a redirect is executed, the
     exception is catched and we check that the targetURL is correct)
     Case redirect without url parameter
     """
     request_data = self.get_request()
     relay_state = 'http://sp.example.com'
     request_data['get_data']['RelayState'] = relay_state
     auth = OneLogin_Saml2_Auth(request_data, old_settings=self.loadSettingsJSON())
     target_url = auth.redirect_to()
     self.assertEqual(target_url, relay_state)
Пример #17
0
    def testGetSettings(self):
        """
        Tests the get_settings method of the OneLogin_Saml2_Auth class
        Build a OneLogin_Saml2_Settings object with a setting array
        and compare the value returned from the method of the
        auth object
        """
        settings_info = self.loadSettingsJSON()
        settings = OneLogin_Saml2_Settings(settings_info)
        auth = OneLogin_Saml2_Auth(self.get_request(), old_settings=settings_info)

        auth_settings = auth.get_settings()
        self.assertEqual(settings.get_sp_data(), auth_settings.get_sp_data())
def callback():
    auth = OneLogin_Saml2_Auth(prepare_saml_request(request),
                               current_app.config["SAML"])
    auth.process_response()
    errors = auth.get_errors()
    if len(errors) == 0:
        auth_attrs = auth.get_attributes()
        mappings = current_app.config["SAML"]["attributes"]
        attrs = {
            key: auth_attrs[mapping][0]
            for key, mapping in mappings.items()
        }

        user = User.query.get(attrs["uid"])
        if not user:
            user = User(id=attrs["uid"],
                        name=attrs["sn"],
                        first_name=attrs["givenName"],
                        email=attrs["email"])
            db.session.add(user)
            db.session.commit()

        session["logged_in"] = True
        session["user_id"] = user.id
        session["first_name"] = user.first_name
        session["name"] = user.name
        session["email"] = user.email
        session["admin"] = user.admin

        # To do : create function to avoid duplication with pub_page '/moderate'
        if user.admin:
            chans = get_moderate_channels_for_user(user)
            pubs_per_chan = (db.session.query(Publishing).filter(
                (Publishing.channel_id == c.id) & (Publishing.state == 0))
                             for c in chans)
            flattened_list_pubs = [y for x in pubs_per_chan for y in x]
            session["notification"] = len(flattened_list_pubs)
        else:
            session["notification"] = 0

        # Redirect to desired url
        self_url = OneLogin_Saml2_Utils.get_self_url(
            prepare_saml_request(request))
        if 'RelayState' in request.form and self_url != request.form[
                'RelayState']:
            return redirect(auth.redirect_to(request.form['RelayState']))
    else:
        return make_response(", ".join(errors), 500)

    return make_response("saml_acs_error", 500)
Пример #19
0
def init_saml_auth():
    parsed_url = urlparse(request.url)
    request_data = {
        "https": "on" if request.scheme == "https" else "off",
        "http_host": request.host,
        "server_port": parsed_url.port,
        "script_name": request.path,
        "get_data": request.args.copy(),
        "post_data": request.form.copy(),
        "query_string": request.query_string
        }

    auth = OneLogin_Saml2_Auth(request_data, custom_base_path=get_env("INFRABOX_ACCOUNT_SAML_SETTINGS_PATH"))
    return auth
Пример #20
0
def login(request):
    """Kick off a SAML login request."""
    req = prepare_django_request(request)
    saml_auth = OneLogin_Saml2_Auth(
        req, old_settings=settings.ONELOGIN_SAML_SETTINGS)
    if 'next' in request.GET:
        redirect_to = OneLogin_Saml2_Utils.get_self_url(
            req) + request.GET['next']
    else:
        redirect_to = OneLogin_Saml2_Utils.get_self_url(
            req) + settings.SAML_LOGIN_REDIRECT
    url = saml_auth.login(redirect_to)
    request.session['AuthNRequestID'] = saml_auth.get_last_request_id()
    return HttpResponseRedirect(url)
Пример #21
0
    def testLoginWithUnicodeSettings(self):
        """
        Tests the login method of the OneLogin_Saml2_Auth class
        Case Login with unicode settings. An AuthnRequest is built an redirect executed
        """
        settings_info = self.loadSettingsJSON('settings6.json')
        request_data = self.get_request()
        auth = OneLogin_Saml2_Auth(request_data, old_settings=settings_info)

        target_url = auth.login()
        parsed_query = parse_qs(urlparse(target_url)[4])
        hostname = OneLogin_Saml2_Utils.get_self_host(request_data)
        self.assertIn(u'http://%s/index.html' % hostname,
                      parsed_query['RelayState'])
Пример #22
0
    def testBuildRequestSignature(self):
        """
        Tests the build_request_signature method of the OneLogin_Saml2_Auth
        """
        settings = self.loadSettingsJSON()
        message = self.file_contents(
            join(self.data_path, 'logout_requests',
                 'logout_request_deflated.xml.base64'))
        relay_state = 'http://relaystate.com'
        auth = OneLogin_Saml2_Auth(self.get_request(), old_settings=settings)

        signature = auth.build_request_signature(message, relay_state)
        valid_signature = 'Pb1EXAX5TyipSJ1SndEKZstLQTsT+1D00IZAhEepBM+OkAZQSToivu3njgJu47HZiZAqgXZFgloBuuWE/+GdcSsRYEMkEkiSDWTpUr25zKYLJDSg6GNo6iAHsKSuFt46Z54Xe/keYxYP03Hdy97EwuuSjBzzgRc5tmpV+KC7+a0='
        self.assertEqual(signature, valid_signature)

        settings['sp']['privatekey'] = ''
        settings['custom_base_path'] = u'invalid/path/'
        auth2 = OneLogin_Saml2_Auth(self.get_request(), old_settings=settings)
        with self.assertRaisesRegexp(
                OneLogin_Saml2_Error,
                "Trying to sign the SAMLRequest but can't load the SP private key"
        ):
            auth2.build_request_signature(message, relay_state)
Пример #23
0
    def testGetLastLogoutRequest(self):
        settings = self.loadSettingsJSON()
        auth = OneLogin_Saml2_Auth(
            {
                'http_host': 'localhost',
                'script_name': 'thing'
            },
            old_settings=settings)
        auth.logout()
        expectedFragment = (
            '        Destination="http://idp.example.com/SingleLogoutService.php">\n'
            '        <saml:Issuer>http://stuff.com/endpoints/metadata.php</saml:Issuer>\n'
            '        <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity" SPNameQualifier="http://stuff.com/endpoints/metadata.php">http://idp.example.com/</saml:NameID>\n'
            '        \n    </samlp:LogoutRequest>')
        self.assertIn(expectedFragment, auth.get_last_request_xml())

        request = self.file_contents(
            join(self.data_path, 'logout_requests', 'logout_request.xml'))
        message = OneLogin_Saml2_Utils.deflate_and_base64_encode(request)
        message_wrapper = {'get_data': {'SAMLRequest': message}}
        auth = OneLogin_Saml2_Auth(message_wrapper, old_settings=settings)
        auth.process_slo()
        self.assertEqual(request, auth.get_last_request_xml())
Пример #24
0
def init_saml_auth(req, saml_path):
    """
    Init SAML authentication for remote application.

    Args:
        req(dict):
        saml_path(str): The path to the configuration files for python3-saml.

    Returns:
        The SAML SP instance.

    """
    auth = OneLogin_Saml2_Auth(req, custom_base_path=saml_path)
    return auth
Пример #25
0
    def testBuildResponseSignature(self):
        """
        Tests the build_response_signature method of the OneLogin_Saml2_Auth
        """
        settings = self.loadSettingsJSON()
        message = self.file_contents(
            join(self.data_path, 'logout_responses',
                 'logout_response_deflated.xml.base64'))
        relay_state = 'http://relaystate.com'
        auth = OneLogin_Saml2_Auth(self.get_request(), old_settings=settings)

        signature = auth.build_response_signature(message, relay_state)
        valid_signature = 'IcyWLRX6Dz3wHBfpcUaNLVDMGM3uo6z2Z11Gjq0/APPJaHboKGljffsgMVAGBml497yckq+eYKmmz+jpURV9yTj2sF9qfD6CwX2dEzSzMdRzB40X7pWyHgEJGIhs6BhaOt5oXEk4T+h3AczERqpVYFpL00yo7FNtyQkhZFpHFhM='
        self.assertEqual(signature, valid_signature)

        settings['sp']['privatekey'] = ''
        settings['custom_base_path'] = u'invalid/path/'
        auth2 = OneLogin_Saml2_Auth(self.get_request(), old_settings=settings)
        with self.assertRaisesRegexp(
                OneLogin_Saml2_Error,
                "Trying to sign the SAMLResponse but can't load the SP private key"
        ):
            auth2.build_response_signature(message, relay_state)
Пример #26
0
    def callback(self, auth_storage):
        req = prepare_request(self._settings)
        input_data = web.input()

        auth = OneLogin_Saml2_Auth(req, self._settings)
        auth.process_response()
        errors = auth.get_errors()

        # Try and check if IdP is using several signature certificates
        # This is a limitation of python3-saml
        for cert in self._settings["idp"].get("additionalX509certs", []):
            if auth.get_last_error_reason() == "Signature validation failed. SAML Response rejected":
                # Change used IdP certificate
                logging.getLogger('inginious.webapp.plugin.auth.saml').debug("Trying another certificate...")
                new_settings = copy.deepcopy(self._settings)
                new_settings["idp"]["x509cert"] = cert
                # Retry processing response
                auth = OneLogin_Saml2_Auth(req, new_settings)
                auth.process_response()
                errors = auth.get_errors()

        if len(errors) == 0 and "attributes" in self._settings:
            attrs = auth.get_attributes()
            username = attrs[self._settings["attributes"]["uid"]][0]
            realname = attrs[self._settings["attributes"]["cn"]][0]
            email = attrs[self._settings["attributes"]["email"]][0]

            # Redirect to desired url
            self_url = OneLogin_Saml2_Utils.get_self_url(req)
            if 'RelayState' in input_data and self_url != input_data['RelayState']:
                redirect_url = auth.redirect_to(input_data['RelayState'])
                # Initialize session in user manager and update cache
                return (str(username), realname, email) if redirect_url == auth_storage["redir_url"] else None
        else:
            logging.getLogger('inginious.webapp.plugin.auth.saml').error("Errors while processing response : ",
                                                                         ", ".join(errors))
            return None
Пример #27
0
def build_auth(request, saml_config):
    """
    Construct a OneLogin_Saml2_Auth object for the current request.
    """
    url = urlparse(options.get("system.url-prefix"))
    saml_request = {
        "https": "on" if url.scheme == "https" else "off",
        "http_host": url.hostname,
        "script_name": request.META["PATH_INFO"],
        "server_port": url.port,
        "get_data": request.GET.copy(),
        "post_data": request.POST.copy(),
    }

    return OneLogin_Saml2_Auth(saml_request, saml_config)
Пример #28
0
async def saml_login_callback(request: Request):
    req = await prepare_from_fastapi_request(request, True)
    auth = OneLogin_Saml2_Auth(req, saml_settings)
    auth.process_response()  # Process IdP response
    errors = auth.get_errors()  # This method receives an array with the errors
    if len(errors) == 0:
        if not auth.is_authenticated(
        ):  # This check if the response was ok and the user data retrieved or not (user authenticated)
            return "user Not authenticated"
        else:
            return "User authenticated"
    else:
        print("Error when processing SAML Response: %s %s" %
              (', '.join(errors), auth.get_last_error_reason()))
        return "Error in callback"
Пример #29
0
def build_auth(request, saml_config):
    """
    Construct a OneLogin_Saml2_Auth object for the current request.
    """
    url = urlparse(options.get('system.url-prefix'))
    saml_request = {
        'https': 'on' if url.scheme == 'https' else 'off',
        'http_host': url.hostname,
        'script_name': request.META['PATH_INFO'],
        'server_port': url.port,
        'get_data': request.GET.copy(),
        'post_data': request.POST.copy()
    }

    return OneLogin_Saml2_Auth(saml_request, saml_config)
Пример #30
0
    def POST(self):

        if not EXTRA_MODULES['onelogin']:
            header('X-Rucio-Auth-Token', None)
            return "SAML not configured on the server side."

        SAML_PATH = config_get('saml', 'config_path')
        req = prepare_saml_request(ctx.env, dict(param_input()))
        auth = OneLogin_Saml2_Auth(req, custom_base_path=SAML_PATH)

        auth.process_response()
        errors = auth.get_errors()
        if not errors:
            if auth.is_authenticated():
                setcookie('saml-nameid', value=auth.get_nameid(), path='/')