Пример #1
0
def digest_auth(qop=None, user="******", passwd="passwd"):
    """Prompts the user for authorization using HTTP Digest auth"""
    if qop not in ("auth", "auth-int"):
        qop = None
    if not request.headers.get("Authorization"):
        response = app.make_response("")
        response.status_code = 401

        # RFC2616 Section4.2: HTTP headers are ASCII.  That means
        # request.remote_addr was originally ASCII, so I should be able to
        # encode it back to ascii.  Also, RFC2617 says about nonces: "The
        # contents of the nonce are implementation dependent"
        nonce = H(
            b"".join(
                [
                    getattr(request, "remote_addr", u"").encode("ascii"),
                    b":",
                    str(time.time()).encode("ascii"),
                    b":",
                    os.urandom(10),
                ]
            )
        )
        opaque = H(os.urandom(10))

        auth = WWWAuthenticate("digest")
        auth.set_digest(
            "*****@*****.**", nonce, opaque=opaque, qop=("auth", "auth-int") if qop is None else (qop,)
        )
        response.headers["WWW-Authenticate"] = auth.to_header()
        response.headers["Set-Cookie"] = "fake=fake_value"
        return response
    elif not (check_digest_auth(user, passwd) and request.headers.get("Cookie")):
        return status_code(401)
    return jsonify(authenticated=True, user=user)
Пример #2
0
def digest_auth(qop=None, user='******', passwd='passwd'):
    """Prompts the user for authorization using HTTP Digest auth"""
    if qop not in ('auth', 'auth-int'):
        qop = None
    if 'Authorization' not in request.headers or  \
                       not check_digest_auth(user, passwd) or \
                       not 'Cookie' in request.headers:
        response = app.make_response('')
        response.status_code = 401

        # RFC2616 Section4.2: HTTP headers are ASCII.  That means
        # request.remote_addr was originally ASCII, so I should be able to
        # encode it back to ascii.  Also, RFC2617 says about nonces: "The
        # contents of the nonce are implementation dependent"
        nonce = H(b''.join([
            getattr(request,'remote_addr',u'').encode('ascii'),
            b':',
            str(time.time()).encode('ascii'),
            b':',
            os.urandom(10)
        ]))
        opaque = H(os.urandom(10))

        auth = WWWAuthenticate("digest")
        auth.set_digest('*****@*****.**', nonce, opaque=opaque,
                        qop=('auth', 'auth-int') if qop is None else (qop, ))
        response.headers['WWW-Authenticate'] = auth.to_header()
        response.headers['Set-Cookie'] = 'fake=fake_value'
        return response
    return jsonify(authenticated=True, user=user)
Пример #3
0
def handle_unauthorized():
    authenticate = WWWAuthenticate()
    authenticate.set_basic('AdminLDAP Login')
    response = make_response(error_response(
        u'Authentifizierung erforderlich',401))
    response.headers['WWW-Authenticate'] = authenticate.to_header()
    return response
Пример #4
0
def digest_auth(qop=None, user='******', passwd='passwd', algorithm='MD5'):
    """Prompts the user for authorization using HTTP Digest auth"""
    if algorithm not in ('MD5', 'SHA-256'):
        algorithm = 'MD5'
    if qop not in ('auth', 'auth-int'):
        qop = None
    if 'Authorization' not in request.headers or  \
                       not check_digest_auth(user, passwd) or \
                       'Cookie' not in request.headers:
        response = app.make_response('')
        response.status_code = 401

        # RFC2616 Section4.2: HTTP headers are ASCII.  That means
        # request.remote_addr was originally ASCII, so I should be able to
        # encode it back to ascii.  Also, RFC2617 says about nonces: "The
        # contents of the nonce are implementation dependent"
        nonce = H(
            b''.join([
                getattr(request, 'remote_addr', u'').encode('ascii'), b':',
                str(time.time()).encode('ascii'), b':',
                os.urandom(10)
            ]), "MD5")
        opaque = H(os.urandom(10), "MD5")

        auth = WWWAuthenticate("digest")
        auth.set_digest('*****@*****.**',
                        nonce,
                        opaque=opaque,
                        qop=('auth', 'auth-int') if qop is None else (qop, ),
                        algorithm=algorithm)
        response.headers['WWW-Authenticate'] = auth.to_header()
        response.headers['Set-Cookie'] = 'fake=fake_value'
        return response
    return jsonify(authenticated=True, user=user)
Пример #5
0
def parse_www_authenticate_header(value, on_update = None):
    if not value:
        return WWWAuthenticate(on_update=on_update)
    try:
        auth_type, auth_info = value.split(None, 1)
        auth_type = auth_type.lower()
    except (ValueError, AttributeError):
        return WWWAuthenticate(value.strip().lower(), on_update=on_update)

    return WWWAuthenticate(auth_type, parse_dict_header(auth_info), on_update)
Пример #6
0
def digest_auth(qop=None, user='******', passwd='passwd', checkCookie=True):
    """Prompts the user for authorization using HTTP Digest auth"""
    if qop not in ('auth', 'auth-int'):
        qop = None
    try:
        remoteAddr = request.remote_addr or u''
        authInHeaders = 'Authorization' in request.headers
        digestCheck = authInHeaders and request.headers.get(
            'Authorization').startswith('Digest ')
        authCheck = authInHeaders and digestCheck and check_digest_auth(
            user, passwd)
        if not all([authInHeaders, digestCheck, authCheck]):
            # RFC2616 Section4.2: HTTP headers are ASCII.  That means
            # request.remote_addr was originally ASCII, so I should be able to
            # encode it back to ascii.  Also, RFC2617 says about nonces: "The
            # contents of the nonce are implementation dependent"
            nonce = H(b':'.join([
                remoteAddr.encode('ascii'),
                str(time.time()).encode('ascii'),
                os.urandom(10)
            ]))
            opaque = H(os.urandom(10))

            response = app.make_response(
                jsonify(authenticated=False,
                        user=user,
                        authInHeaders=authInHeaders,
                        digestCheck=digestCheck,
                        authCheck=authCheck,
                        headers=dict(request.headers)))
            response.status_code = 401

            auth = WWWAuthenticate("digest")
            auth.set_digest('*****@*****.**',
                            nonce,
                            opaque=opaque,
                            qop=('auth', 'auth-int') if qop is None else
                            (qop, ))
            response.headers['WWW-Authenticate'] = auth.to_header()
            if checkCookie is True:
                response.headers['Set-Cookie'] = 'auth=%s' % remoteAddr
            return response
        elif checkCookie is True and request.cookies.get('auth') != remoteAddr:
            # check for auth challange cookie per https://github.com/Runscope/httpbin/issues/124
            response = app.make_response(
                'Missing the cookie set in the 401 response. '
                'This client seems broken. To bypass this check use the digest-auth-nocookie route.'
            )
            response.status_code = 403
            return response
    except Exception as e:
        response = app.make_response('Error: %s' % str(e))
        response.status_code = 500
        return response
    return jsonify(authenticated=True, user=user)
Пример #7
0
    def __init__(self, error=None, status=401, headers=None):
        www_auth_header = WWWAuthenticate(auth_type="Bearer")
        www_auth_header["realm"] = "api.districtr.org"

        if error is not None:
            www_auth_header["error"] = error

        if headers is None:
            headers = dict()
        headers["WWW-Authenticate"] = www_auth_header.to_header()

        super().__init__(None, status, headers)
Пример #8
0
def parse_www_authenticate_header(value, on_update=None):
    """Parse an HTTP WWW-Authenticate header into a :class:`WWWAuthenticate`
    object.

    :param value: a WWW-Authenticate header to parse.
    :param on_update: an optional callable that is called every time a
                      value on the :class:`WWWAuthenticate` object is changed.
    :return: a :class:`WWWAuthenticate` object.
    """
    if not value:
        return WWWAuthenticate(on_update=on_update)
    try:
        auth_type, auth_info = value.split(None, 1)
        auth_type = auth_type.lower()
    except (ValueError, AttributeError):
        return WWWAuthenticate(value.lower(), on_update=on_update)
    return WWWAuthenticate(auth_type, parse_dict_header(auth_info), on_update)
Пример #9
0
def digest_auth(qop=None, user='******', passwd='passwd', checkCookie=True):
    """Prompts the user for authorization using HTTP Digest auth"""
    if qop not in ('auth', 'auth-int'):
        qop = None
    try:
        remoteAddr = request.remote_addr or u''
        authInHeaders = 'Authorization' in request.headers
        digestCheck = authInHeaders and request.headers.get('Authorization').startswith('Digest ')
        authCheck = authInHeaders and digestCheck and check_digest_auth(user, passwd)
        if not all([authInHeaders, digestCheck, authCheck]):
            # RFC2616 Section4.2: HTTP headers are ASCII.  That means
            # request.remote_addr was originally ASCII, so I should be able to
            # encode it back to ascii.  Also, RFC2617 says about nonces: "The
            # contents of the nonce are implementation dependent"
            nonce = H(b':'.join([
                remoteAddr.encode('ascii'),
                str(time.time()).encode('ascii'),
                os.urandom(10)
            ]))
            opaque = H(os.urandom(10))
            
            response = app.make_response(jsonify(
                authenticated=False, user=user, authInHeaders=authInHeaders,
                digestCheck=digestCheck, authCheck=authCheck,
                headers=dict(request.headers)))
            response.status_code = 401
            
            auth = WWWAuthenticate("digest")
            auth.set_digest('*****@*****.**', nonce, opaque=opaque,
                            qop=('auth', 'auth-int') if qop is None else (qop, ))
            response.headers['WWW-Authenticate'] = auth.to_header()
            if checkCookie is True:
                response.headers['Set-Cookie'] = 'auth=%s' % remoteAddr
            return response
        elif checkCookie is True and request.cookies.get('auth') != remoteAddr:
            # check for auth challange cookie per https://github.com/Runscope/httpbin/issues/124
            response = app.make_response('Missing the cookie set in the 401 response. '
                'This client seems broken. To bypass this check use the digest-auth-nocookie route.')
            response.status_code = 403
            return response
    except Exception as e:
        response = app.make_response('Error: %s' % str(e))
        response.status_code = 500
        return response
    return jsonify(authenticated=True, user=user)
Пример #10
0
def test_unauthorized_www_authenticate():
    basic = WWWAuthenticate()
    basic.set_basic("test")
    digest = WWWAuthenticate()
    digest.set_digest("test", "test")

    exc = exceptions.Unauthorized(www_authenticate=basic)
    h = dict(exc.get_headers({}))
    assert h["WWW-Authenticate"] == str(basic)

    exc = exceptions.Unauthorized(www_authenticate=[digest, basic])
    h = dict(exc.get_headers({}))
    assert h["WWW-Authenticate"] == ", ".join((str(digest), str(basic)))
Пример #11
0
def digest_auth(qop=None, user="******", passwd="passwd"):
    """Prompts the user for authorization using HTTP Digest auth"""
    if qop not in ("auth", "auth-int"):
        qop = None
    if not request.headers.get("Authorization"):
        response = app.make_response("")
        response.status_code = 401

        nonce = H("%s:%d:%s" % (request.remote_addr, time.time(), os.urandom(10)))
        opaque = H(os.urandom(10))

        auth = WWWAuthenticate("digest")
        auth.set_digest(
            "*****@*****.**", nonce, opaque=opaque, qop=("auth", "auth-int") if qop is None else (qop,)
        )
        response.headers["WWW-Authenticate"] = auth.to_header()
        return response
    elif not check_digest_auth(user, passwd):
        return status_code(401)
    return jsonify(authenticated=True, user=user)
Пример #12
0
def digest_auth(qop=None, user='******', passwd='passwd'):
    """Prompts the user for authorization using HTTP Digest auth"""
    if qop not in ('auth', 'auth-int'):
        qop = None
    if not request.headers.get('Authorization'):
        response = app.make_response('')
        response.status_code = 401

        nonce = H("%s:%d:%s" % (request.remote_addr,
                                  time.time(),
                                  os.urandom(10)))
        opaque = H(os.urandom(10))

        auth = WWWAuthenticate("digest")
        auth.set_digest('*****@*****.**', nonce, opaque=opaque,
                        qop=('auth', 'auth-int') if qop is None else (qop, ))
        response.headers['WWW-Authenticate'] = auth.to_header()
        return response
    elif not check_digest_auth(user, passwd):
        return status_code(403)
    return jsonify(authenticated=True, user=user)
Пример #13
0
def digest_auth(qop=None, user='******', passwd='passwd'):
    """Prompts the user for authorization using HTTP Digest auth"""
    if qop not in ('auth', 'auth-int'):
        qop = None
    if not request.headers.get('Authorization'):
        response = app.make_response('')
        response.status_code = 401

        nonce = H("%s:%d:%s" % (request.remote_addr,
                                  time.time(),
                                  os.urandom(10)))
        opaque = H(os.urandom(10))

        auth = WWWAuthenticate("digest")
        auth.set_digest('*****@*****.**', nonce, opaque=opaque,
                        qop=('auth', 'auth-int') if qop is None else (qop, ))
        response.headers['WWW-Authenticate'] = auth.to_header()
        return response
    elif not check_digest_auth(user, passwd):
        return status_code(403)
    return dict(authenticated=True, user=user)
Пример #14
0
def digest_challenge_response(app, qop, algorithm, stale=False):
    response = app.make_response('')
    response.status_code = 401

    # RFC2616 Section4.2: HTTP headers are ASCII.  That means
    # request.remote_addr was originally ASCII, so I should be able to
    # encode it back to ascii.  Also, RFC2617 says about nonces: "The
    # contents of the nonce are implementation dependent"
    nonce = H(
        b''.join([
            getattr(request, 'remote_addr', u'').encode('ascii'), b':',
            str(time.time()).encode('ascii'), b':',
            os.urandom(10)
        ]), "MD5")
    opaque = H(os.urandom(10), "MD5")

    auth = WWWAuthenticate("digest")
    auth.set_digest('*****@*****.**',
                    nonce,
                    opaque=opaque,
                    qop=('auth', 'auth-int') if qop is None else (qop, ),
                    algorithm=algorithm)
    auth.stale = stale
    response.headers['WWW-Authenticate'] = auth.to_header()
    return response
Пример #15
0
def digest_challenge_response(app, qop, algorithm, stale = False):
    response = app.make_response('')
    response.status_code = 401

    # RFC2616 Section4.2: HTTP headers are ASCII.  That means
    # request.remote_addr was originally ASCII, so I should be able to
    # encode it back to ascii.  Also, RFC2617 says about nonces: "The
    # contents of the nonce are implementation dependent"
    nonce = H(b''.join([
        getattr(request, 'remote_addr', u'').encode('ascii'),
        b':',
        str(time.time()).encode('ascii'),
        b':',
        os.urandom(10)
    ]), algorithm)
    opaque = H(os.urandom(10), algorithm)

    auth = WWWAuthenticate("digest")
    auth.set_digest('*****@*****.**', nonce, opaque=opaque,
                    qop=('auth', 'auth-int') if qop is None else (qop,), algorithm=algorithm)
    auth.stale = stale
    response.headers['WWW-Authenticate'] = auth.to_header()
    return response
Пример #16
0
def test_unauthorized_www_authenticate():
    basic = WWWAuthenticate()
    basic.set_basic("test")
    digest = WWWAuthenticate()
    digest.set_digest("test", "test")

    exc = exceptions.Unauthorized(www_authenticate=basic)
    h = Headers(exc.get_headers({}))
    assert h["WWW-Authenticate"] == str(basic)

    exc = exceptions.Unauthorized(www_authenticate=[digest, basic])
    h = Headers(exc.get_headers({}))
    assert h.get_all("WWW-Authenticate") == [str(digest), str(basic)]

    exc = exceptions.Unauthorized()
    h = Headers(exc.get_headers({}))
    assert "WWW-Authenticate" not in h
Пример #17
0
def test_unauthorized_www_authenticate():
    basic = WWWAuthenticate()
    basic.set_basic("test")
    digest = WWWAuthenticate()
    digest.set_digest("test", "test")

    exc = exceptions.Unauthorized(www_authenticate=basic)
    h = dict(exc.get_headers({}))
    assert h['WWW-Authenticate'] == str(basic)

    exc = exceptions.Unauthorized(www_authenticate=[digest, basic])
    h = dict(exc.get_headers({}))
    assert h['WWW-Authenticate'] == ', '.join((str(digest), str(basic)))
Пример #18
0
"""
Exceptions for the API.
"""
import inspect
import logging
import werkzeug.exceptions
from flask import jsonify
from typing import Any
from werkzeug.exceptions import Unauthorized
from werkzeug.datastructures import WWWAuthenticate
from .utils import export

LOG = logging.getLogger(__name__)

WWW_AUTHENTICATE = WWWAuthenticate("basic", {"realm": "api"})


@export
class AuthenticationRequired(Unauthorized):
    """
    A specialized :class:`werkzeug.exceptions.Unauthorized` with a preset
    ``WWW-Authenticate`` header.
    """
    def get_headers(self, *args, **kwargs):
        """
        Unconditionally adds a statically defined ``WWW-Authenticate`` header
        using :const:`WWW_AUTHENTICATE`.

        This will be rendered unnecessary when the latest dev version of
        werkzeug is released, as it has another mechanism for passing through
        the header value.
Пример #19
0
 def unauthorized():
     auth = WWWAuthenticate()
     auth.set_basic()
     abort(401, www_authenticate=auth)
Пример #20
0
 def _create_unauthorized(description, realm=DEFAULT_REALM):
     www_authenticate = WWWAuthenticate()
     www_authenticate.set_basic(realm=realm)
     return Unauthorized(description=description,
                         www_authenticate=www_authenticate.to_header())
Пример #21
0
 def handle(_: WSGIEnvironment, __: StartResponse) -> Iterable[bytes]:
     raise Unauthorized("Foo < Bar",
                        www_authenticate=WWWAuthenticate("Test"))
Пример #22
0
 def on_update(www_auth: WWWAuthenticate) -> None:
     if not www_auth and "www-authenticate" in self.headers:
         del self.headers["www-authenticate"]
     elif www_auth:
         self.headers["WWW-Authenticate"] = www_auth.to_header()
Пример #23
0
def get_basic_auth(realm=None):
    basic_auth = WWWAuthenticate()
    basic_auth.set_basic(realm=realm or 'Authentication required')
    return basic_auth.to_header()