Ejemplo n.º 1
0
def get_authn_request(request, came_from, selected_idp,
                      required_loa=None, force_authn=False):
    # Request the right AuthnContext for workmode
    # (AL1 for 'personal', AL2 for 'helpdesk' and AL3 for 'admin' by default)
    if required_loa is None:
        required_loa = request.registry.settings.get('required_loa', {})
        workmode = request.registry.settings.get('workmode')
        required_loa = required_loa.get(workmode, '')
    log.debug('Requesting AuthnContext {!r}'.format(required_loa))
    kwargs = {
        "requested_authn_context": RequestedAuthnContext(
            authn_context_class_ref=AuthnContextClassRef(
                text=required_loa
            )
        ),
        "force_authn": str(force_authn).lower(),
    }

    client = Saml2Client(request.saml2_config)
    try:
        (session_id, info) = client.prepare_for_authenticate(
            entityid=selected_idp, relay_state=came_from,
            binding=BINDING_HTTP_REDIRECT,
            **kwargs
        )
    except TypeError:
        log.error('Unable to know which IdP to use')
        raise

    oq_cache = OutstandingQueriesCache(request.session)
    oq_cache.set(session_id, came_from)
    return info
Ejemplo n.º 2
0
    def test_outstanding_queries(self):

        oqc = OutstandingQueriesCache({})
        oqc._db['user'] = '******'
        oqc._db.sync()

        self.assertEqual(oqc.outstanding_queries(), {'user':
                                                     '******'})
Ejemplo n.º 3
0
def login_view(request):
    login_redirect_url = request.registry.settings.get(
        'saml2.login_redirect_url', '/')

    came_from = request.GET.get('next', login_redirect_url)

    if authenticated_userid(request):
        return HTTPFound(location=came_from)

    selected_idp = request.GET.get('idp', None)

    idps = request.saml2_config.getattr('idp')
    if selected_idp is None and len(idps) > 1:
        log.debug('A discovery process is needed')

        return render_to_response('templates/wayf.jinja2', {
            'available_idps': idps.items(),
            'came_from': came_from,
            'login_url': request.route_url('saml2-login'),
        })

    # Request the right AuthnContext for workmode
    # (AL1 for 'personal', AL2 for 'helpdesk' and AL3 for 'admin' by default)
    required_loa = request.registry.settings.get('required_loa', {})
    workmode = request.registry.settings.get('workmode')
    required_loa = required_loa.get(workmode, '')
    log.debug('Requesting AuthnContext {!r} for workmode {!r}'.format(required_loa, workmode))
    kwargs = {
        "requested_authn_context": RequestedAuthnContext(
            authn_context_class_ref=AuthnContextClassRef(
                text=required_loa
            )
        )
    }

    client = Saml2Client(request.saml2_config)
    try:
        (session_id, result) = client.prepare_for_authenticate(
            entityid=selected_idp, relay_state=came_from,
            binding=BINDING_HTTP_REDIRECT,
            **kwargs
        )
    except TypeError:
        log.error('Unable to know which IdP to use')
        raise

    oq_cache = OutstandingQueriesCache(request.session)
    oq_cache.set(session_id, came_from)

    log.debug('Redirecting the user to the IdP')
    if not request.is_xhr:
        return HTTPFound(location=get_location(result))
    else:
        loginurl = request.route_url('saml2-login',
                                     _query=(('next', request.path),))
        return HTTPXRelocate(loginurl)
Ejemplo n.º 4
0
def assertion_consumer_service(request):
    if 'SAMLResponse' not in request.POST:
        return HTTPBadRequest("Couldn't find 'SAMLResponse' in POST data.")
    xmlstr = request.POST['SAMLResponse']
    client = Saml2Client(request.saml2_config,
                         identity_cache=IdentityCache(request.session))

    oq_cache = OutstandingQueriesCache(request.session)
    outstanding_queries = oq_cache.outstanding_queries()

    try:
        # process the authentication response
        response = client.parse_authn_request_response(xmlstr, BINDING_HTTP_POST,
                                                       outstanding_queries)
    except AssertionError:
        log.error('SAML response is not verified')
        return HTTPBadRequest(
            """SAML response is not verified. May be caused by the response
            was not issued at a reasonable time or the SAML status is not ok.
            Check the IDP datetime setup""")

    if response is None:
        log.error('SAML response is None')
        return HTTPBadRequest(
            "SAML response has errors. Please check the logs")

    session_id = response.session_id()
    oq_cache.delete(session_id)

    # authenticate the remote user
    session_info = response.session_info()

    log.debug('Trying to locate the user authenticated by the IdP')
    log.debug('Session info:\n{!s}\n\n'.format(pprint.pformat(session_info)))

    user = authenticate(request, session_info)
    if user is None:
        log.error('Could not find the user identified by the IdP')
        return HTTPUnauthorized("Access not authorized")

    headers = login(request, session_info, user)

    _set_name_id(request.session, session_info['name_id'])

    # redirect the user to the view where he came from
    relay_state = request.POST.get('RelayState', '/')
    log.debug('Redirecting to the RelayState: ' + relay_state)
    return HTTPFound(location=relay_state, headers=headers)
Ejemplo n.º 5
0
    def add_outstanding_query(self, came_from):

        queryUtility = self.testapp.app.registry.queryUtility
        session_factory = queryUtility(ISessionFactory)
        request = DummyRequest()
        session = session_factory(request)
        session.persist()
        # ensure that session id is a NCName valid
        session._sess.id = "a" + session._sess.id

        oq_cache = OutstandingQueriesCache(session)
        oq_cache.set(session._sess.id, came_from)

        session.persist()

        self.testapp.cookies['beaker.session.id'] = session._sess.id

        return session._sess.id
Ejemplo n.º 6
0
    def test_delete(self):
        oqc = OutstandingQueriesCache({})
        oqc.set('session_id', '/next')
        self.assertEqual(oqc.outstanding_queries(), {'session_id': '/next'})

        oqc.delete('session_id')

        self.assertEqual(oqc.outstanding_queries(), {})