Пример #1
0
def logout_service(request):
    """SAML Logout Response endpoint

    The IdP will send the logout response to this view,
    which will process it with pysaml2 help and log the user
    out.
    Note that the IdP can request a logout even when
    we didn't initiate the process as a single logout
    request started by another SP.
    """
    log.debug('Logout service started')

    state = StateCache(request.session)
    client = Saml2Client(request.saml2_config, state_cache=state,
                         identity_cache=IdentityCache(request.session))
    settings = request.registry.settings

    logout_redirect_url = settings.get('saml2.logout_redirect_url')
    next_page = request.GET.get('next_page', logout_redirect_url)

    if 'SAMLResponse' in request.GET:  # we started the logout
        log.debug('Receiving a logout response from the IdP')
        response = client.parse_logout_request_response(
            request.GET['SAMLResponse'],
            BINDING_HTTP_REDIRECT
        )
        state.sync()
        if response and response.status_ok():
            headers = logout(request)
            return HTTPFound(next_page, headers=headers)
        else:
            log.error('Unknown error during the logout')
            return HTTPBadRequest('Error during logout')

    elif 'SAMLRequest' in request.GET:  # logout started by the IdP
        log.debug('Receiving a logout request from the IdP')
        subject_id = _get_name_id(request.session)
        if subject_id is None:
            log.warning(
                'The session does not contain the subject id for user {0} '
                'Performing local logout'.format(
                    authenticated_userid(request)
                )
            )
            headers = logout(request)
            return HTTPFound(location=next_page, headers=headers)
        else:
            http_info = client.handle_logout_request(
                request.GET['SAMLRequest'],
                subject_id,
                BINDING_HTTP_REDIRECT,
                relay_state=request.GET['RelayState']
            )
            state.sync()
            location = get_location(http_info)
            headers = logout(request)
            return HTTPFound(location=location, headers=headers)
    else:
        log.error('No SAMLResponse or SAMLRequest parameter found')
        raise HTTPNotFound('No SAMLResponse or SAMLRequest parameter found')
Пример #2
0
def logout_view(request):
    """SAML Logout Request initiator

    This view initiates the SAML2 Logout request
    using the pysaml2 library to create the LogoutRequest.
    """
    log.debug('Logout process started')
    state = StateCache(request.session)

    client = Saml2Client(request.saml2_config, state_cache=state,
                         identity_cache=IdentityCache(request.session))
    subject_id = _get_name_id(request.session)
    if subject_id is None:
        log.warning(
            'The session does not contains the subject id for user ')
        location = request.registry.settings.get('saml2.logout_redirect_url')

    else:
        logouts = client.global_logout(subject_id)
        loresponse = logouts.values()[0]
        # loresponse is a dict for REDIRECT binding, and LogoutResponse for SOAP binding
        if isinstance(loresponse, LogoutResponse):
            if loresponse.status_ok():
                log.debug('Performing local logout of {!r}'.format(authenticated_userid(request)))
                headers = logout(request)
                location = request.registry.settings.get('saml2.logout_redirect_url')
                return HTTPFound(location=location, headers=headers)
            else:
                return HTTPInternalServerError('Logout failed')
        headers_tuple = loresponse[1]['headers']
        location = headers_tuple[0][1]

    state.sync()
    log.debug('Redirecting to {!r} to continue the logout process'.format(location))
    return HTTPFound(location=location)