Esempio n. 1
0
    def create_authorization_response(self, grant_user):
        state = self.request.state
        if grant_user:
            self.request.user = grant_user
            client = self.request.client
            token = self.generate_token(
                client, self.GRANT_TYPE,
                user=grant_user,
                scope=self.request.scope,
                include_refresh_token=False
            )
            if self.request.response_type == 'id_token':
                token = {
                    'expires_in': token['expires_in'],
                    'scope': token['scope'],
                }
                token = self._process_implicit_token(token)
            else:
                log.debug('Grant token %r to %r', token, client)
                self.server.save_token(token, self.request)
                token = self._process_implicit_token(token)
            params = [(k, token[k]) for k in token]
            if state:
                params.append(('state', state))
        else:
            error = AccessDeniedError(state=state)
            params = error.get_body()

        # http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes
        response_mode = self.request.data.get('response_mode', self.DEFAULT_RESPONSE_MODE)
        return create_response_mode_response(
            redirect_uri=self.redirect_uri,
            params=params,
            response_mode=response_mode,
        )
Esempio n. 2
0
    def create_authorization_response(self, grant_user):
        state = self.request.state
        if grant_user:
            params = self._create_granted_params(grant_user)
            if state:
                params.append(('state', state))
        else:
            error = AccessDeniedError(state=state)
            params = error.get_body()

        # http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes
        return create_response_mode_response(
            redirect_uri=self.redirect_uri,
            params=params,
            response_mode=self.request.data.get('response_mode'),
        )
Esempio n. 3
0
    def create_authorization_response(self, grant_user):
        """
        Overrides method from authlib---authlib has some peculiarities here such as
        trying to access ``token["scope"]`` from the token response which is not
        following OIDC. This should be creating a response in accordance with the spec
        here:

        https://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthResponse
        """
        state = self.request.state
        if grant_user:
            self.request.user = grant_user
            client = self.request.client
            include_access_token = self.request.response_type == "id_token token"
            nonce = self.request.data.get("nonce")
            token_response = self.generate_token(
                client,
                self.GRANT_TYPE,
                include_access_token=include_access_token,
                user=grant_user,
                scope=self.request.scope,
                nonce=nonce,
            )
            params = [(k, token_response[k]) for k in token_response]
            if state:
                params.append(("state", state))
        else:
            error = AccessDeniedError(state=state)
            params = error.get_body()

        # http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes
        return create_response_mode_response(
            redirect_uri=self.redirect_uri,
            params=params,
            response_mode=self.request.data.get(
                "response_mode", self.DEFAULT_RESPONSE_MODE
            ),
        )
Esempio n. 4
0
    async def create_authorization_response(self, redirect_uri, grant_user):
        state = self.request.state
        if grant_user:
            self.request.user = grant_user

            code = self.generate_authorization_code()
            await self.save_authorization_code(code, self.request)

            params = [("code", code)]
            if state:
                params.append(("state", state))
            uri = add_params_to_uri(redirect_uri, params)
            headers = [('Location', uri)]
            return 302, '', headers

        else:
            raise AccessDeniedError(state=state, redirect_uri=redirect_uri)
Esempio n. 5
0
def _get_auth_response_for_prompts(prompts, grant, user, client, scope):
    """
    Get response based on prompt parameter. TODO: not completely conforming yet

    FIXME: To conform to spec, some of the prompt params should be handled
    before AuthN or if it fails (so adequate and useful errors are provided).

    Right now the behavior is that the endpoint will just continue to
    redirect the user to log in without checking these params....

    Args:
        prompts (TYPE): Description
        grant (TYPE): Description
        user (TYPE): Description
        client (TYPE): Description
        scope (TYPE): Description

    Returns:
        TYPE: Description
    """
    show_consent_screen = True

    if prompts:
        prompts = prompts.split(" ")
        if "none" in prompts:
            # don't auth or consent, error if user not logged in
            show_consent_screen = False

            # if none is here, there shouldn't be others
            if len(prompts) != 1:
                error = InvalidRequestError(state=grant.params.get("state"),
                                            uri=grant.params.get("uri"))
                return _get_authorize_error_response(
                    error, grant.params.get("redirect_uri"))

            try:
                get_current_user()
                response = server.create_authorization_response(user)
            except Unauthorized:
                error = AccessDeniedError(state=grant.params.get("state"),
                                          uri=grant.params.get("uri"))
                return _get_authorize_error_response(
                    error, grant.params.get("redirect_uri"))

        if "login" in prompts:
            show_consent_screen = True
            try:
                # Re-AuthN user (kind of).
                # TODO (RR 2018-03-16): this could also include removing active
                # refresh tokens.
                flask.session.clear()

                # For a POST, return the redirect in JSON instead of headers.
                if flask.request.method == "POST":
                    redirect_response = flask.make_response(
                        flask.jsonify(
                            {"redirect": response.headers["Location"]}))
                else:
                    redirect_response = flask.make_response(
                        flask.redirect(flask.url_for(".authorize")))

                clear_cookies(redirect_response)
                return redirect_response
            except Unauthorized:
                error = AccessDeniedError(state=grant.params.get("state"),
                                          uri=grant.params.get("uri"))
                return _get_authorize_error_response(
                    error, grant.params.get("redirect_uri"))

        if "consent" in prompts:
            # show consent screen (which is default behavior so pass)
            pass

        if "select_account" in prompts:
            # allow user to select one of their accounts, we
            # don't support this at the moment
            pass

    if show_consent_screen:
        shown_scopes = [] if not scope else scope.split(" ")
        if "openid" in shown_scopes:
            shown_scopes.remove("openid")

        enabled_idps = config.get("OPENID_CONNECT", {})
        idp_names = []
        for idp, info in enabled_idps.items():
            # prefer name if its there, then just use the key for the provider
            idp_name = info.get("name") or idp.title()
            idp_names.append(idp_name)

        resource_description = [
            SCOPE_DESCRIPTION[s].format(idp_names=" and ".join(idp_names))
            for s in shown_scopes
        ]

        privacy_policy = config.get("BASE_URL").rstrip("/") + "/privacy-policy"

        response = flask.render_template(
            "oauthorize.html",
            grant=grant,
            user=user,
            client=client,
            app_name=config.get("APP_NAME"),
            resource_description=resource_description,
            privacy_policy=privacy_policy,
        )

    return response