diff --git a/example/idp/idp.app.py b/example/idp/idp.app.py new file mode 100755 index 0000000..ed026a9 --- /dev/null +++ b/example/idp/idp.app.py @@ -0,0 +1,201 @@ +#!/usr/bin/env python + +import re +import base64 +from cgi import escape +import urllib +import urlparse + +from saml2 import server +from saml2.utils import make_instance, sid, decode_base64_and_inflate +from saml2 import samlp, saml +from saml2.time_util import in_a_while, instant + +def authn_response(identity, in_response_to, destination, spid): + global idp + resp = idp.do_sso_response( + destination, # consumer_url + in_response_to, # in_response_to + spid, # sp_entity_id + identity # identity as dictionary + ) + + return ("%s" % resp).split("\n") + +# ----------------------------------------------------------------------------- +def dict_to_table(ava, lev=0, width=1): + txt = [] + txt.append('\n' % width) + for prop, valarr in ava.items(): + txt.append("\n") + if isinstance(valarr, basestring): + txt.append("\n" % str(prop)) + try: + txt.append("\n" % valarr.encode("utf8")) + except AttributeError: + txt.append("\n" % valarr) + elif isinstance(valarr, list): + i = 0 + n = len(valarr) + for val in valarr: + if i == 0: + txt.append("\n") + if isinstance(val, dict): + txt.append("\n") + else: + try: + txt.append("\n" % val.encode("utf8")) + except AttributeError: + txt.append("\n" % val) + if n > 1: + txt.append("\n") + n -= 1 + i += 1 + elif isinstance(valarr, dict): + txt.append("\n" % prop) + txt.append("\n") + txt.append("\n") + txt.append('
%s%s%s%s\n" % (len(valarr),prop)) + else: + txt.append("
\n") + txt.extend(dict_to_table(val, lev+1, width-1)) + txt.append("%s%s
%s\n") + txt.extend(dict_to_table(valarr, lev+1, width-1)) + txt.append("
\n') + return txt + +REPOZE_ID_EQUIVALENT = "uid" +FORM_SPEC = """
+ + +
""" + +def sso(environ, start_response, user, logger): + """ Supposted to return a POST """ + #edict = dict_to_table(environ) + logger and logger.info("Environ keys: %s" % environ.keys()) + if "QUERY_STRING" in environ: + logger and logger.info("Query string: %s" % environ["QUERY_STRING"]) + query = urlparse.parse_qs(environ["QUERY_STRING"]) + elif "s2repoze.qinfo" in environ: + query = environ["s2repoze.qinfo"] + # base 64 encoded request + (consumer, identifier, policies, + spid) = idp.parse_authn_request(query["SAMLRequest"][0]) + spentityid = query["spentityid"][0] + try: + relayState = query["RelayState"][0] + except (KeyError, AttributeError): + relayState = "/" + start_response('200 OK', [('Content-Type', 'text/html')]) + identity = dict(environ["repoze.who.identity"]["user"]) + if REPOZE_ID_EQUIVALENT: + identity[REPOZE_ID_EQUIVALENT] = ( + environ["repoze.who.identity"]['repoze.who.userid']) + authn_resp = authn_response(identity, identifier, consumer, spid) + logger and logger.info("AuthNResponse: %s" % authn_resp) + response = [] + response.append("") + response.append("SAML 2.0 POST") + response.append("") + #login_url = location + '?spentityid=' + "lingon.catalogix.se" + response.append(FORM_SPEC % (consumer, + base64.b64encode("".join(authn_resp)),"/")) + response.append("""""") + response.append("") + return response + +def whoami(environ, start_response, user, logger): + start_response('200 OK', [('Content-Type', 'text/html')]) + identity = environ["repoze.who.identity"].copy() + for prop in ["login", "password"]: + try: + del identity[prop] + except KeyError: + continue + response = dict_to_table(identity) + return response[:] + +def not_found(environ, start_response, logger): + """Called if no URL matches.""" + start_response('404 NOT FOUND', [('Content-Type', 'text/plain')]) + return ['Not Found'] + +def not_authn(environ, start_response, logger): + if "QUERY_STRING" in environ: + query = urlparse.parse_qs(environ["QUERY_STRING"]) + logger and logger.info("query: %s" % query) + start_response('401 Unauthorized', [('Content-Type', 'text/plain')]) + return ['Unknown user'] + +# ---------------------------------------------------------------------------- + +# map urls to functions +urls = [ + (r'whoami$', whoami), + (r'whoami/(.*)$', whoami), + (r'sso$', sso), + (r'sso/(.*)$', sso), +] + +# ---------------------------------------------------------------------------- + +def application(environ, start_response): + """ + The main WSGI application. Dispatch the current request to + the functions from above and store the regular expression + captures in the WSGI environment as `myapp.url_args` so that + the functions from above can access the url placeholders. + + If nothing matches call the `not_found` function. + + :param environ: The HTTP application environment + :param start_response: The application to run when the handling of the + request is done + :return: The response as a list of lines + """ + user = environ.get("REMOTE_USER", "") + if not user: + user = environ.get("repoze.who.identity", "") + + path = environ.get('PATH_INFO', '').lstrip('/') + logger = environ.get('repoze.who.logger') + logger and logger.info( " PATH: %s" % path) + for regex, callback in urls: + if user: + match = re.search(regex, path) + if match is not None: + try: + environ['myapp.url_args'] = match.groups()[0] + except IndexError: + environ['myapp.url_args'] = path + return callback(environ, start_response, user, logger) + else: + logger and logger.info("-- No USER --") + return not_authn(environ, start_response, logger) + return not_found(environ, start_response, logger) + +# ---------------------------------------------------------------------------- + +from repoze.who.config import make_middleware_with_config + +app_with_auth = make_middleware_with_config(application, {"here":"."}, + './who.ini', log_file="idpapp.log") + +# ---------------------------------------------------------------------------- + +if __name__ == '__main__': + import sys + from wsgiref.simple_server import make_server + import logging + LOG_FILENAME = "./idp.log" + PORT = 8088 + + logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG) + + idp = server.Server(sys.argv[1], logging) + srv = make_server('localhost', PORT, app_with_auth) + print "listening on port: %s" % PORT + srv.serve_forever() \ No newline at end of file diff --git a/example/idp/idp.conf b/example/idp/idp.conf new file mode 100644 index 0000000..c7c0d55 --- /dev/null +++ b/example/idp/idp.conf @@ -0,0 +1,12 @@ +{ + "entityid" : "urn:mace:umu.se:saml:roland:idp", + "service": ["idp"], + "my_name" : "Rolands IdP", + "debug" : 1, + "key_file" : "./mykey.pem", + "cert_file" : "./mycert.pem", + "xmlsec_binary" : "/opt/local/bin/xmlsec1", + "metadata" : { + "local": ["metadata.xml"], + } +} \ No newline at end of file diff --git a/example/idp/metadata.xml b/example/idp/metadata.xml new file mode 100644 index 0000000..1766c0a --- /dev/null +++ b/example/idp/metadata.xml @@ -0,0 +1,34 @@ + +MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV +BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx +EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz +MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l +YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw +DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7 +bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC +FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR +mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW +BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9 +o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW +BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE +AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF +BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO +zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN ++vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI= +http://www.umu.se/Umea UniversityRolandHedbergroland.hedberg@adm.umu.seMIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV +BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx +EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz +MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l +YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw +DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7 +bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC +FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR +mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW +BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9 +o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW +BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE +AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF +BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO +zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN ++vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI= +http://www.umu.se/Umea UniversityRolandHedbergroland.hedberg@adm.umu.se diff --git a/example/idp/mycert.pem b/example/idp/mycert.pem new file mode 100644 index 0000000..d4a0873 --- /dev/null +++ b/example/idp/mycert.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV +BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx +EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz +MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l +YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw +DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7 +bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC +FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR +mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW +BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9 +o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW +BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE +AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF +BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO +zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN ++vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI= +-----END CERTIFICATE----- diff --git a/example/idp/mykey.pem b/example/idp/mykey.pem new file mode 100644 index 0000000..d9ec5f8 --- /dev/null +++ b/example/idp/mykey.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDkJWP7bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr +6/ROgW96ZeQ57fzVy2MCFiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43 +qCfLx+clUlOvtnsoMiiRmo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQAB +AoGAbx9rKH91DCw/ZEPhHsVXJ6cYHxGcMoAWvnMMC9WUN+bNo4gNL205DLfsxXA1 +jqXFXZj3+38vSFumGPA6IvXrN+Wyp3+Lz3QGc4K5OdHeBtYlxa6EsrxPgvuxYDUB +vx3xdWPMjy06G/ML+pR9XHnRaPNubXQX3UxGBuLjwNXVmyECQQD2/D84tYoCGWoq +5FhUBxFUy2nnOLKYC/GGxBTX62iLfMQ3fbQcdg2pJsB5rrniyZf7UL+9FOsAO9k1 +8DO7G12DAkEA7Hkdg1KEw4ZfjnnjEa+KqpyLTLRQ91uTVW6kzR+4zY719iUJ/PXE +PxJqm1ot7mJd1LW+bWtjLpxs7jYH19V+kQJBAIEpn2JnxdmdMuFlcy/WVmDy09pg +0z0imdexeXkFmjHAONkQOv3bWv+HzYaVMo8AgCOksfEPHGqN4eUMTfFeuUMCQF+5 +E1JSd/2yCkJhYqKJHae8oMLXByNqRXTCyiFioutK4JPYIHfugJdLfC4QziD+Xp85 +RrGCU+7NUWcIJhqfiJECQAIgUAzfzhdj5AyICaFPaOQ+N8FVMLcTyqeTXP0sIlFk +JStVibemTRCbxdXXM7OVipz1oW3PBVEO3t/VyjiaGGg= +-----END RSA PRIVATE KEY----- diff --git a/example/idp/who.ini b/example/idp/who.ini new file mode 100644 index 0000000..7ae28e7 --- /dev/null +++ b/example/idp/who.ini @@ -0,0 +1,55 @@ +[plugin:form] +# identificaion and challenge +use = s2repoze.plugins.formswithhidden:make_plugin +login_form_qs = __do_login +rememberer_name = auth_tkt +#form = %(here)s/login_form.html + +[plugin:auth_tkt] +# identification +use = repoze.who.plugins.auth_tkt:make_plugin +secret = cassiopeja +cookie_name = kustrask +secure = False +include_ip = False + +[plugin:basicauth] +# identification and challenge +use = repoze.who.plugins.basicauth:make_plugin +realm = 'sample' + +[plugin:htpasswd] +# authentication +use = repoze.who.plugins.htpasswd:make_plugin +filename = %(here)s/passwd +check_fn = repoze.who.plugins.htpasswd:crypt_check + +[plugin:ini] +use = s2repoze.plugins.ini:make_plugin +ini_file = %(here)s/user.ini + +[general] +request_classifier = repoze.who.classifiers:default_request_classifier +challenge_decider = repoze.who.classifiers:default_challenge_decider +remote_user_key = REMOTE_USER + +[identifiers] +# plugin_name;classifier_name:.. or just plugin_name (good for any) +plugins = + form;browser + auth_tkt + basicauth + +[authenticators] +# plugin_name;classifier_name.. or just plugin_name (good for any) +plugins = + htpasswd + +[challengers] +# plugin_name;classifier_name:.. or just plugin_name (good for any) +plugins = + form;browser + basicauth + +[mdproviders] +plugins = ini diff --git a/example/sp/application.py b/example/sp/application.py new file mode 100755 index 0000000..542a137 --- /dev/null +++ b/example/sp/application.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python + +import re +from cgi import escape +import urllib + +# ----------------------------------------------------------------------------- +def dict_to_table(ava, width=1): + txt = [] + txt.append('\n' % width) + for prop, valarr in ava.items(): + txt.append("\n") + if isinstance(valarr, basestring): + txt.append("\n" % str(prop)) + try: + txt.append("\n" % valarr.encode("utf8")) + except AttributeError: + txt.append("\n" % valarr) + elif isinstance(valarr, list): + i = 0 + n = len(valarr) + for val in valarr: + if i == 0: + txt.append("\n") + if isinstance(val, dict): + txt.append("\n") + else: + try: + txt.append("\n" % val.encode("utf8")) + except AttributeError: + txt.append("\n" % val) + if n > 1: + txt.append("\n") + n -= 1 + i += 1 + elif isinstance(valarr, dict): + txt.append("\n" % prop) + txt.append("\n") + txt.append("\n") + txt.append('
%s%s%s%s\n" % (len(valarr),prop)) + else: + txt.append("
\n") + txt.extend(dict_to_table(val, lev+1, width-1)) + txt.append("%s%s
%s\n") + txt.extend(dict_to_table(valarr, lev+1, width-1)) + txt.append("
\n') + return txt + + +def whoami(environ, start_response, user, logger): + start_response('200 OK', [('Content-Type', 'text/html')]) + identity = environ["repoze.who.identity"]["user"] + response = dict_to_table(identity) + return response[:] + +def not_found(environ, start_response): + """Called if no URL matches.""" + start_response('404 NOT FOUND', [('Content-Type', 'text/plain')]) + return ['Not Found'] + +def not_authn(environ, start_response): + start_response('401 Unauthorized', [('Content-Type', 'text/plain')]) + return ['Unknown user'] + +# ---------------------------------------------------------------------------- + +# map urls to functions +urls = [ + (r'whoami$', whoami), +] + +# ---------------------------------------------------------------------------- + +def application(environ, start_response): + """ + The main WSGI application. Dispatch the current request to + the functions from above and store the regular expression + captures in the WSGI environment as `myapp.url_args` so that + the functions from above can access the url placeholders. + + If nothing matches call the `not_found` function. + + :param environ: The HTTP application environment + :param start_response: The application to run when the handling of the + request is done + :return: The response as a list of lines + """ + user = environ.get("REMOTE_USER", "") + if not user: + user = environ.get("repoze.who.identity", "") + + path = environ.get('PATH_INFO', '').lstrip('/') + logger = environ.get('repoze.who.logger') + logger and logger.info( " PATH: %s" % path) + for regex, callback in urls: + if user: + match = re.search(regex, path) + if match is not None: + try: + environ['myapp.url_args'] = match.groups()[0] + except IndexError: + environ['myapp.url_args'] = path + return callback(environ, start_response, user, logger) + else: + return not_authn(environ, start_response) + return not_found(environ, start_response) + +# ---------------------------------------------------------------------------- + +from repoze.who.config import make_middleware_with_config + +app_with_auth = make_middleware_with_config(application, {"here":"."}, + './who_saml2.ini', log_file="repo.log") + +# ---------------------------------------------------------------------------- + +if __name__ == '__main__': + from wsgiref.simple_server import make_server + srv = make_server('localhost', 8087, app_with_auth) + srv.serve_forever() \ No newline at end of file diff --git a/example/sp/mycert.pem b/example/sp/mycert.pem new file mode 100644 index 0000000..d4a0873 --- /dev/null +++ b/example/sp/mycert.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV +BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx +EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz +MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l +YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw +DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7 +bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC +FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR +mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW +BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9 +o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW +BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE +AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF +BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO +zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN ++vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI= +-----END CERTIFICATE----- diff --git a/example/sp/mykey.pem b/example/sp/mykey.pem new file mode 100644 index 0000000..d9ec5f8 --- /dev/null +++ b/example/sp/mykey.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDkJWP7bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr +6/ROgW96ZeQ57fzVy2MCFiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43 +qCfLx+clUlOvtnsoMiiRmo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQAB +AoGAbx9rKH91DCw/ZEPhHsVXJ6cYHxGcMoAWvnMMC9WUN+bNo4gNL205DLfsxXA1 +jqXFXZj3+38vSFumGPA6IvXrN+Wyp3+Lz3QGc4K5OdHeBtYlxa6EsrxPgvuxYDUB +vx3xdWPMjy06G/ML+pR9XHnRaPNubXQX3UxGBuLjwNXVmyECQQD2/D84tYoCGWoq +5FhUBxFUy2nnOLKYC/GGxBTX62iLfMQ3fbQcdg2pJsB5rrniyZf7UL+9FOsAO9k1 +8DO7G12DAkEA7Hkdg1KEw4ZfjnnjEa+KqpyLTLRQ91uTVW6kzR+4zY719iUJ/PXE +PxJqm1ot7mJd1LW+bWtjLpxs7jYH19V+kQJBAIEpn2JnxdmdMuFlcy/WVmDy09pg +0z0imdexeXkFmjHAONkQOv3bWv+HzYaVMo8AgCOksfEPHGqN4eUMTfFeuUMCQF+5 +E1JSd/2yCkJhYqKJHae8oMLXByNqRXTCyiFioutK4JPYIHfugJdLfC4QziD+Xp85 +RrGCU+7NUWcIJhqfiJECQAIgUAzfzhdj5AyICaFPaOQ+N8FVMLcTyqeTXP0sIlFk +JStVibemTRCbxdXXM7OVipz1oW3PBVEO3t/VyjiaGGg= +-----END RSA PRIVATE KEY----- diff --git a/example/sp/sp_conf.py b/example/sp/sp_conf.py new file mode 100644 index 0000000..4ce6458 --- /dev/null +++ b/example/sp/sp_conf.py @@ -0,0 +1,24 @@ +{ + "service": ["sp"], + "entityid" : "urn:mace:example.com:saml:sp", + "service_url" : "http://example.com:8087/", + "idp_url" : "https://example.com/saml2/idp/SSOService.php", + "my_name" : "My first SP", + "debug" : 1, + "key_file" : "./mykey.pem", + "cert_file" : "./mycert.pem", + "xmlsec_binary" : "/opt/local/bin/xmlsec1", + "organization": { + "name": "Example Co", + #display_name + "url":"http://www.example.com/", + }, + "contact": [{ + "given_name":"John", + "sur_name": "Smith", + "email_address": "john.smith@example.com", + #contact_type + #company + #telephone_number + }] +} \ No newline at end of file diff --git a/example/sp/who.ini b/example/sp/who.ini new file mode 100644 index 0000000..984652f --- /dev/null +++ b/example/sp/who.ini @@ -0,0 +1,54 @@ +[plugin:auth_tkt] +# identification +use = repoze.who.plugins.auth_tkt:make_plugin +secret = kasamark +cookie_name = pysaml2 +secure = False +include_ip = False +timeout = 3600 +reissue_time = 3000 + +# IDENTIFIER +# @param : +# - rememberer_name : name of the plugin for remembering (delegate) +[plugin:saml2auth] +use = s2repoze.plugins.sp:make_plugin +saml_conf = sp_conf.py +rememberer_name = auth_tkt +debug = 1 +path_logout = .*/logout.* + + +# CHALLENGE DECIDER +# @param: +# - path_login : those regexp indicate which url should be redirected for a challenge +# e.g. : for SAML2, will be redirected on a "/saml2/login" like url +[plugin:decider] +use = repoze.who.plugins.saml2.challenge_decider:make_plugin +path_login = + .*/login$ + + +[general] +request_classifier = repoze.who.classifiers:default_request_classifier +remote_user_key = REMOTE_USER +# trick : target the plugin whose name is the same +challenge_decider = decider + + +[identifiers] +# plugin_name;classifier_name:.. or just plugin_name (good for any) +plugins = + saml2auth + auth_tkt + +[authenticators] +# plugin_name;classifier_name.. or just plugin_name (good for any) +plugins = saml2auth + +[challengers] +# plugin_name;classifier_name:.. or just plugin_name (good for any) +plugins = saml2auth + +[mdproviders] +plugins = saml2auth