def get_authn_req_url(self, session, acr, forceAuthN, scope, forceConsent,
                          allowConsentOptionDeselection, response_type,
                          ui_locales, max_age):
        """
        :param session: the session, will be used to keep the OAuth state
        :param acr: The acr to request
        :param force_authn: Force the resource owner to authenticate even though a session exist
        :return redirect url for the OAuth code flow
        """
        state = tools.generate_random_string()
        session['state'] = state
        session[
            'code_verifier'] = code_verifier = tools.generate_random_string(
                100)
        session["flow"] = response_type

        code_challenge = tools.base64_urlencode(
            hashlib.sha256(code_verifier).digest())

        request_args = {
            'scope': scope,
            'response_type': response_type,
            'client_id': self.config['client_id'],
            'state': state,
            'code_challenge': code_challenge,
            'code_challenge_method': "S256",
            'redirect_uri': self.config['redirect_uri']
        }

        if 'authn_parameters' in self.config:
            request_args.update(self.config['authn_parameters'])

        if acr: request_args["acr_values"] = acr

        if ui_locales: request_args["ui_locales"] = ui_locales

        if max_age: request_args["max_age"] = max_age

        if forceAuthN: request_args["prompt"] = "login"

        if forceConsent:
            if allowConsentOptionDeselection:
                request_args["prompt"] = request_args.get(
                    "prompt", "") + " consent consent_allow_deselection"
            else:
                request_args["prompt"] = request_args.get("prompt",
                                                          "") + " consent"

        if response_type.find("id_token"):
            request_args["nonce"] = session[
                "nonce"] = tools.generate_random_string()

        delimiter = "?" if self.config['authorization_endpoint'].find(
            "?") < 0 else "&"
        login_url = "%s%s%s" % (self.config['authorization_endpoint'],
                                delimiter, urllib.urlencode(request_args))

        print "Redirect to %s" % login_url

        return login_url
Exemple #2
0
 def get_authn_req_url(self, session):
     """
     :param session: the session, will be used to keep the OAuth state
     :return redirect url for the OAuth code flow
     """
     state = tools.generate_random_string()
     session['state'] = state
     request_args = self.__authn_req_args(state)
     login_url = "%s?%s" % (self.config['authorization_endpoint'],
                            urllib.urlencode(request_args))
     print "Redirect to federation service %s" % login_url
     return login_url
Exemple #3
0
def oauth_callback():
    """
    Called when the resource owner is returning from the authorization server
    :return:redirect to / with user info stored in the session.
    """
    if 'state' not in session or session['state'] != request.args['state']:
        return create_error('Missing or invalid state')

    if 'code' not in request.args:
        return create_error('No code in response')

    if "code_verifier" not in session:
        return create_error("No code_verifier in session")

    try:
        token_data = _client.get_token(request.args['code'],
                                       session["code_verifier"])
    except Exception as e:
        return create_error('Could not fetch token(s)', e)
    session.pop('state', None)

    # Store in basic server session, since flask session use cookie for storage
    user = UserSession()

    if 'access_token' in token_data:
        user.access_token = token_data['access_token']

    if _jwt_validator and 'id_token' in token_data:
        # validate JWS; signature, aud and iss.
        # Token type, access token, ref-token and JWT
        if 'issuer' not in _config:
            return create_error(
                'Could not validate token: no issuer configured')

        try:
            _jwt_validator.validate(token_data['id_token'], _config['issuer'],
                                    _config['audience'])
        except BadSignature as bs:
            return create_error('Could not validate token: %s' % bs.message)
        except Exception as ve:
            return create_error("Unexpected exception: %s" % ve.message)

        user.id_token = token_data['id_token']

    if 'refresh_token' in token_data:
        user.refresh_token = token_data['refresh_token']

    session['session_id'] = generate_random_string()
    _session_store[session['session_id']] = user

    return redirect_with_baseurl('/')
Exemple #4
0
def ajax_callback():
    user = callback(request.form)

    user.front_end_id_token = request.form.get("id_token", "")
    user.front_end_access_token = request.form.get("access_token", "")

    if "session_id" in session:
        _session_store[session['session_id']] = user
    else:
        # New session. Unexpected since code flow would normally be done first. Make a new session instead
        session['session_id'] = generate_random_string()
        _session_store[session['session_id']] = user

    return "ok"
Exemple #5
0
    def get_authn_req_url(self, session, acr, forceAuthN, scope):
        """
        :param session: the session, will be used to keep the OAuth state
        :return redirect url for the OAuth code flow
        """
        state = tools.generate_random_string()
        session['state'] = state
        session[
            'code_verifier'] = code_verifier = tools.generate_random_string(
                100)

        code_challenge = tools.base64_urlencode(
            hashlib.sha256(code_verifier).digest())

        request_args = self.__authn_req_args(state, scope, code_challenge,
                                             "S256")
        if acr: request_args["acr_values"] = acr
        if forceAuthN: request_args["prompt"] = "login"
        delimiter = "?" if self.config['authorization_endpoint'].find(
            "?") < 0 else "&"
        login_url = "%s%s%s" % (self.config['authorization_endpoint'],
                                delimiter, urllib.urlencode(request_args))
        print "Redirect to federation service %s" % login_url
        return login_url
Exemple #6
0
def oauth_callback():
    """
    Called when the resource owner is returning from the authorization server
    :return:redirect to / with user info stored in the session.
    """
    if session.get("flow", None) != "code":
        # This is the callback for a hybrid or implicit flow
        return render_template('index.html')

    user = callback(request.args)

    session['session_id'] = generate_random_string()
    _session_store[session['session_id']] = user

    return redirect_with_baseurl('/')
Exemple #7
0
 def get_authn_req_url(self, session, acr, force_authn):
     """
     :param session: the session, will be used to keep the OAuth state
     :param acr: The acr to request
     :param force_authn: Force the resource owner to authenticate even though a session exist
     :return redirect url for the OAuth code flow
     """
     state = tools.generate_random_string()
     session['state'] = state
     request_args = self.__authn_req_args(state)
     if acr: request_args["acr_values"] = acr
     if force_authn: request_args["prompt"] = "login"
     login_url = "%s?%s" % (self.config['authorization_endpoint'],
                            urllib.urlencode(request_args))
     print "Redirect to Authorization Server %s" % login_url
     return login_url
Exemple #8
0
def oauth_callback():
    """
    Called when the resource owner is returning from the authorization server
    :return:redirect to / with user info stored in the session.
    """
    if 'state' not in session or session['state'] != request.args['state']:
        return create_error('Missing or invalid state')

    if 'code' not in request.args:
        return create_error('No code in response')

    try:
        token_data = _client.get_token(request.args['code'])
    except Exception as e:
        return create_error('Could not fetch token(s)', e)
    session.pop('state', None)

    # Store in basic server session, since flask session use cookie for storage
    user = UserSession()

    if 'access_token' in token_data:
        user.access_token = token_data['access_token']

    if 'id_token' in token_data:
        # Assignment 5
        # validate JWS; signature, aud and iss.
        user.id_token = token_data['id_token']

    if 'access_token' in token_data:
        user.access_token = token_data['access_token']

    if 'refresh_token' in token_data:
        user.refresh_token = token_data['refresh_token']

    session['session_id'] = generate_random_string()
    _session_store[session['session_id']] = user

    return redirect_with_baseurl('/')
Exemple #9
0
def ajax_callback():
    if 'state' not in session or session['state'] != request.form['state']:
        abort(400)  # TODO: Provide nicer error to AJAX client

    if "code_verifier" not in session:
        abort(400)

    if 'code' not in request.form:
        abort(400)

    user = callback(request.form)

    user.front_end_id_token = request.form.get("id_token", "")
    user.front_end_access_token = request.form.get("access_token", "")

    if "session_id" in session:
        _session_store[session['session_id']] = user
    else:
        # New session. Unexpected since code flow would normally be done first. Make a new session instead
        session['session_id'] = generate_random_string()
        _session_store[session['session_id']] = user

    return "ok"
Exemple #10
0
def start(config):
    # load the config
    global _config
    _config = config

    global _client
    _client = Client(_config)

    # load the jwk set.
    if 'jwks_uri' in _config:
        global _jwt_validator
        _jwt_validator = JwtValidator(_config)
    else:
        print 'Found no url to JWK set, will not be able to validate JWT signature.'

    # initiate the app
    _app.secret_key = generate_random_string()

    # some default values
    _debug = 'debug' in _config and _config['debug']

    if 'port' in _config:
        port = _config['port']
    else:
        port = 5443

    if _debug:
        print 'Running conf:'
        print_json(_config)

    if 'disable_https' in _config and _config['disable_https']:
        _app.run('0.0.0.0', debug=_debug, port=port)
    else:
        _app.run('0.0.0.0',
                 debug=_debug,
                 port=port,
                 ssl_context=('keys/localhost.pem', 'keys/localhost.pem'))
Exemple #11
0
def oauth_callback():
    """
    Called when the resource owner is returning from the authorization server
    :return:redirect to / with user info stored in the session.
    """
    if session.get("flow", None) != "code":
        # This is the callback for a hybrid or implicit flow
        return render_template('index.html')

    if 'state' not in session or session['state'] != request.args['state']:
        return create_error('Missing or invalid state')

    if "code_verifier" not in session:
        return create_error("No code_verifier in session")

    if 'code' not in request.args:
        return create_error('No code in response')

    user = callback(request.args)

    session['session_id'] = generate_random_string()
    _session_store[session['session_id']] = user

    return redirect_with_baseurl('/')
Exemple #12
0
    _config = load_config()

    _client = Client(_config)

    # load the jwk set.
    if 'jwks_uri' in _config:
        _jwt_validator = JwtValidator(_config)
    else:
        print 'Found no url to JWK set, will not be able to validate JWT signature.'
        _jwt_validator = None

    # create a session store
    _session_store = {}

    # initiate the app
    _app.secret_key = generate_random_string()

    # some default values
    if 'port' in _config:
        port = int(_config['port'])
    else:
        port = 5443

    _disable_https = 'disable_https' in _config and _config['disable_https']

    if 'base_url' not in _config:
        _config['base_url'] = 'https://localhost:%i' % port

    debug = _config['debug'] = 'debug' in _config and _config['debug']

    if debug:
    def get_authn_req_url(self, session, acr, forceAuthN, scope, forceConsent, allowConsentOptionDeselection,
                          response_type, ui_locales, max_age, claims, send_parameters_via):
        """
        :param session: the session, will be used to keep the OAuth state
        :param acr: The acr to request
        :param force_authn: Force the resource owner to authenticate even though a session exist
        :return redirect url for the OAuth code flow
        """
        state = tools.generate_random_string()
        session['state'] = state
        session['code_verifier'] = code_verifier = tools.generate_random_string(100)
        session["flow"] = response_type

        code_challenge = tools.base64_urlencode(hashlib.sha256(code_verifier).digest())

        request_args = {'scope': scope,
                        'response_type': response_type,
                        'client_id': self.config['client_id'],
                        'state': state,
                        'code_challenge': code_challenge,
                        'code_challenge_method': "S256",
                        'redirect_uri': self.config.get('redirect_uri', "")}

        if 'authn_parameters' in self.config:
            request_args.update(self.config['authn_parameters'])

        if acr: request_args["acr_values"] = acr

        if ui_locales: request_args["ui_locales"] = ui_locales

        if max_age: request_args["max_age"] = max_age

        if forceAuthN: request_args["prompt"] = "login"

        if claims: request_args["claims"] = claims

        if forceConsent:
            if allowConsentOptionDeselection:
                request_args["prompt"] = request_args.get("prompt", "") + " consent consent_allow_deselection"
            else:
                request_args["prompt"] = request_args.get("prompt", "") + " consent"

        if response_type.find("id_token"):
            request_args["nonce"] = session["nonce"] = tools.generate_random_string()

        delimiter = "?" if self.config['authorization_endpoint'].find("?") < 0 else "&"

        if send_parameters_via == "request_object":
            request_object_claims = request_args
            request_object_claims.update(dict(
                issuer=self.config["client_id"],
                aud=self.config["issuer"],
                exp=int(time.time()) + 180,  # Expires in 3 minutes
                purpose="request"  # FIXME: Required for Curity's implementation of request object (for some reason)
            ))
            request_args = dict(
                request=make_request_object(request_object_claims, self.config.get("request_object_key", None)),
                client_id=request_args["client_id"],
                code_challenge=request_args["code_challenge"],  # FIXME: Curity can't currently handle PCKE if not
                code_challenge_method=request_args["code_challenge_method"],  # provided on query string
                scope=request_args["scope"],
                response_type=request_args["response_type"],
                redirect_uri=request_args["redirect_uri"]  # FIXME: Curity requires this even if in request obj
            )
        elif send_parameters_via == "request_uri":
            request_args = None  # TODO: Implement request URI support

        login_url = "%s%s%s" % (self.config['authorization_endpoint'], delimiter, urllib.urlencode(request_args))

        print "Redirect to %s" % login_url

        return login_url
Exemple #14
0
 def random_password(self, length=int):
     excluded_password_chars = ['\n', '\t', '\r', '\x0b', '\x0c']
     return tools.generate_random_string(
         length, excluded_chars=excluded_password_chars)