コード例 #1
0
ファイル: test_util.py プロジェクト: ibrsp/s2sproxy
    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
コード例 #2
0
 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())
     setattr(
         self.idp_config, 'attribute_converters',
         ac_factory('testenv/attributemaps',
                    **{'override_types': self._all_attributes}))
     self.server = SpidServer(config=self.idp_config)
     self._setup_app_routes()
     # setup custom methods in order to
     # prepare the login form and verify the challenge (optional)
     # for every spid level (1-2-3)
     self.authn_broker = AuthnBroker()
     for index, _level in enumerate(self._spid_levels):
         self.authn_broker.add(
             authn_context_class_ref(_level),
             getattr(self, '_verify_spid_{}'.format(index + 1)))
コード例 #3
0
ファイル: views.py プロジェクト: sieroshtan/djangosaml2idp
    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 e:
            return HttpResponseBadRequest(e)

        try:
            sp_config = settings.SAML_IDP_SPCONFIG[sp_entity_id]
        except Exception:
            raise ImproperlyConfigured("No config for SP %s defined in SAML_IDP_SPCONFIG" % sp_entity_id)

        binding_out, destination = self.IDP.pick_binding(
            service="assertion_consumer_service",
            entity_id=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)

        req_authn_context = PASSWORD
        AUTHN_BROKER = AuthnBroker()
        AUTHN_BROKER.add(authn_context_class_ref(req_authn_context), "")

        # 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=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
            authn_resp = self.IDP.create_authn_response(
                identity=identity,
                in_response_to="IdP_Initiated_Login",
                destination=destination,
                sp_entity_id=sp_entity_id,
                userid=request.user.username,
                name_id=name_id,
                authn=authn,
                sign_response=sign_response,
                sign_assertion=sign_assertion,
                **passed_data)
        except Exception as excp:
            return HttpResponseServerError(excp)

        # 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'])
コード例 #4
0
 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)
コード例 #5
0
def test_authn_2():
    authn = AuthnBroker()
    target = "https://example.org/login"
    authn.add(AUTHNCTXT, target, 10, "https://example.org")

    result = authn.pick(REQAUTHNCTXT)
    assert len(result) == 1
    method, reference = result[0]
    assert target == method
コード例 #6
0
ファイル: handler.py プロジェクト: simudream/IdProxy
 def setup_authn_broker(self, base_url, sphandler, authorization):
     ab = AuthnBroker()
     sphandler.sp_authentication = SpAuthentication(self, sphandler)
     cas_auth = CasAuth(self, self.cas_server, self.service_url)
     password_auth = PasswordYubikeyAuth(self,
                                         self.passwd,
                                         password=True,
                                         yubikey=False)
     yubikey_auth = PasswordYubikeyAuth(self,
                                        self.passwd,
                                        password=False,
                                        yubikey=True)
     password_yubikey_auth = PasswordYubikeyAuth(self,
                                                 self.passwd,
                                                 password=True,
                                                 yubikey=True)
     for authkey, value in authorization.items():
         level = str(value[IdPHandler.AUTHORIZATION_WEIGHT])
         url = value[IdPHandler.AUTHORIZATION_URL]
         acr = value[IdPHandler.AUTHORIZATION_ACR]
         user_info = value[IdPHandler.AUTHORIZATION_USER_INFO]
         if authkey == IdPHandler.AUTHORIZATION_SAML:
             sphandler.sp_authentication.user_info(user_info)
             ab.add(acr, sphandler.sp_authentication, level, url)
         elif authkey == IdPHandler.AUTHORIZATION_CAS:
             cas_auth.user_info(user_info)
             ab.add(acr, cas_auth, level, url)
         elif authkey == IdPHandler.AUTHORIZATION_PASSWORD_YUBIKEY:
             password_yubikey_auth.user_info(user_info)
             ab.add(acr, password_yubikey_auth, level, url)
         elif authkey == IdPHandler.AUTHORIZATION_PASSWORD:
             password_auth.user_info(user_info)
             ab.add(acr, password_auth, level, url)
         elif authkey == IdPHandler.AUTHORIZATION_YUBIKEY:
             yubikey_auth.user_info(user_info)
             ab.add(acr, yubikey_auth, level, url)
         elif authkey == IdPHandler.AUTHORIZATION_MULTIPLEAUTHN:
             authn_list = []
             for m_items in value[IdPHandler.AUTHENTICATION_AUTHNLIST]:
                 m_authkey = m_items[IdPHandler.AUTHORIZATION_ACR]
                 if m_authkey == IdPHandler.AUTHORIZATION_SAML:
                     authn_list.append(sphandler.sp_authentication)
                 elif m_authkey == IdPHandler.AUTHORIZATION_CAS:
                     authn_list.append(cas_auth)
                 elif m_authkey == IdPHandler.AUTHORIZATION_PASSWORD_YUBIKEY:
                     authn_list.append(password_yubikey_auth)
                 elif m_authkey == IdPHandler.AUTHORIZATION_PASSWORD:
                     authn_list.append(password_auth)
                 elif m_authkey == IdPHandler.AUTHORIZATION_YUBIKEY:
                     authn_list.append(yubikey_auth)
             ab.add(acr, MultipleAuthentication(self, authn_list,
                                                user_info), level, url)
         else:
             ab.add(authn_context_class_ref(UNSPECIFIED),
                    UnspecifiedAuth(self), level, url)
     return ab
コード例 #7
0
def test_authn_1():
    ac = authn_context_class_ref(PASSWORDPROTECTEDTRANSPORT)
    rac = requested_authn_context(PASSWORDPROTECTEDTRANSPORT)
    authn = AuthnBroker()
    target = "https://example.org/login"
    authn.add(ac, target, 1, "http://www.example.com")

    result = authn.pick(rac)
    assert len(result) == 1
    method, reference = result[0]
    assert target == method
コード例 #8
0
def test_authn_3():
    authn = AuthnBroker()
    level = 0
    for ref in [AL1, AL2, AL3, AL4]:
        level += 4
        ac = authn_context_class_ref(ref)

        authn.add(ac, REF2METHOD[ref], level,
                  "https://www.example.com/%s" % "al%d" % level)

    rac = requested_authn_context(AL1, "minimum")

    info = authn.pick(rac)
    assert len(info) == 4
    method, ref = info[0]
    assert REF2METHOD[AL1] == method

    rac = requested_authn_context(AL2, "minimum")

    info = authn.pick(rac)
    assert len(info) == 3
    method, ref = info[0]
    assert REF2METHOD[AL2] == method

    rac = requested_authn_context(AL3, "minimum")

    info = authn.pick(rac)
    assert len(info) == 2
    method, ref = info[0]
    assert REF2METHOD[AL3] == method

    rac = requested_authn_context(AL4, "minimum")

    info = authn.pick(rac)
    assert len(info) == 1
    method, ref = info[0]
    assert REF2METHOD[AL4] == method

    rac = requested_authn_context(AL1, "exact")

    info = authn.pick(rac)
    assert len(info) == 1
    method, ref = info[0]
    assert REF2METHOD[AL1] == method

    rac = requested_authn_context(AL1, "better")

    info = authn.pick(rac)
    assert len(info) == 3
コード例 #9
0
    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
コード例 #10
0
ファイル: util.py プロジェクト: trsau/SATOSA
    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
コード例 #11
0
    def __init__(self, config):
        baseurl = config['protocol'] + "://" + config['url']
        log.info("Application baseurl: " + baseurl)

        # Update URLs with base
        for pro in SSIXASAMLProvider_SERVICE_EP:
            for serv in SSIXASAMLProvider_SERVICE_EP[pro]['endpoints']:
                if 'service' in serv:
                    for ep in SSIXASAMLProvider_SERVICE_EP[pro]['endpoints'][
                            serv]:
                        SSIXASAMLProvider_SERVICE_EP[pro]['endpoints'][serv][
                            0] = baseurl + ep[0]

        # Update SAML config
        config['saml_config'].update({'service': SSIXASAMLProvider_SERVICE_EP})
        cfg = SAMLIdpConfig(config['saml_config'])

        # Create SAML IdP server - Init super class after config preparation
        super(SSIXASAMLProvider, self).__init__(config=cfg, cache=Cache())

        # Add authn broker
        self.authn_broker = AuthnBroker()
        self.userinfodb = SAMLUserInfoDB()
        i = BlockchainAuthMethod(baseurl + "/saml", config['proxymode'],
                                 config, self.userinfodb, config['trustmodel'])
        self.authn_broker.add(authn_context_class_ref(UNSPECIFIED), i, 3,
                              {i.acr})

        # Add attribute converters
        self.config.attribute_converters = ac_factory()

        # Add metadata
        self.metadata = self.create_metadata(config['saml_config']['metadata'])

        # Response bindings that are offered
        self.response_bindings = [BINDING_HTTP_POST, BINDING_HTTP_REDIRECT]

        # Default claims
        self.defaul_claims = copy.deepcopy(
            config['saml_config']['default_claims'])
コード例 #12
0
ファイル: assurance.py プロジェクト: kelidas/eduid-IdP
def init_AuthnBroker(my_id):
    """
    Create and return a saml2 AuthnBroker.

    :param my_id: The IdP entity id as string
    :return: AuthnBroker instance

    :type my_id: string
    :rtype: AuthnBroker
    """
    # NOTE: The function pointers supplied to the AUTHN_BROKER is not for authentication,
    # but for displaying proper login forms it seems. In eduid_idp, a single function
    # is used to display login screen regardless of Authn method, so a simple '1' is used
    # instead of the function pointer (has to evaulate to true).
    AUTHN_BROKER = AuthnBroker()
    AUTHN_BROKER.add(EDUID_INTERNAL_3,
                     1,
                     300,
                     my_id,
                     reference=EDUID_INTERNAL_3_NAME + ':300')
    AUTHN_BROKER.add(EDUID_INTERNAL_2,
                     1,
                     200,
                     my_id,
                     reference=EDUID_INTERNAL_2_NAME + ':200')
    AUTHN_BROKER.add(EDUID_INTERNAL_1,
                     1,
                     100,
                     my_id,
                     reference=EDUID_INTERNAL_1_NAME + ':100')
    AUTHN_BROKER.add(EDUID_INTERNAL_UNSPECIFIED,
                     "",
                     0,
                     my_id,
                     reference="eduid.se:level:unspecified")
    return AUTHN_BROKER
コード例 #13
0
ファイル: idp.py プロジェクト: vivekdhayaal/pysaml2
                        help="The ID of the entities descriptor")
    parser.add_argument('-k',
                        dest='keyfile',
                        help="A file with a key to sign the metadata with")
    parser.add_argument('-n', dest='name')
    parser.add_argument('-s',
                        dest='sign',
                        action='store_true',
                        help="sign the metadata")
    parser.add_argument('-m', dest='mako_root', default="./")
    parser.add_argument(dest="config")
    args = parser.parse_args()

    CONFIG = importlib.import_module(args.config)

    AUTHN_BROKER = AuthnBroker()
    AUTHN_BROKER.add(authn_context_class_ref(PASSWORD),
                     username_password_authn, 10, CONFIG.BASE)
    AUTHN_BROKER.add(authn_context_class_ref(UNSPECIFIED), "", 0, CONFIG.BASE)

    IDP = server.Server(args.config, cache=Cache())
    IDP.ticket = {}

    _rot = args.mako_root
    LOOKUP = TemplateLookup(directories=[_rot + 'templates', _rot + 'htdocs'],
                            module_directory=_rot + 'modules',
                            input_encoding='utf-8',
                            output_encoding='utf-8')

    HOST = CONFIG.HOST
    PORT = CONFIG.PORT
コード例 #14
0
ファイル: views.py プロジェクト: singhravi1/djangosaml2idp
    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)
コード例 #15
0
ファイル: views.py プロジェクト: saundersmatt/djangosaml2idp
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'])
コード例 #16
0
    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'])
コード例 #17
0
    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)
コード例 #18
0
ファイル: views.py プロジェクト: sieroshtan/djangosaml2idp
    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)
コード例 #19
0
 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'])