Exemplo n.º 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)
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 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)
Exemplo n.º 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)
Exemplo n.º 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)
Exemplo n.º 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)
Exemplo n.º 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)
Exemplo n.º 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)
Exemplo n.º 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)))
Exemplo n.º 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)
Exemplo n.º 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)
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 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
Exemplo n.º 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
Exemplo n.º 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)))
Exemplo n.º 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.
Exemplo n.º 19
0
 def unauthorized():
     auth = WWWAuthenticate()
     auth.set_basic()
     abort(401, www_authenticate=auth)
Exemplo n.º 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())
Exemplo n.º 21
0
 def handle(_: WSGIEnvironment, __: StartResponse) -> Iterable[bytes]:
     raise Unauthorized("Foo < Bar",
                        www_authenticate=WWWAuthenticate("Test"))
Exemplo n.º 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()
Exemplo n.º 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()