Exemplo n.º 1
0
    def authenticate_oidc_refresh_token(
            self,
            client_id: str = None,
            refresh_token: str = None,
            client_secret: str = None,
            provider_id: str = None) -> 'Connection':
        """
        OpenId Connect Refresh Token

        WARNING: this API is in experimental phase
        """
        provider_id, client_info = self._get_oidc_provider_and_client_info(
            provider_id=provider_id,
            client_id=client_id,
            client_secret=client_secret)

        if refresh_token is None:
            refresh_token = self._get_refresh_token_store().get_refresh_token(
                issuer=client_info.provider.issuer,
                client_id=client_info.client_id)
            if refresh_token is None:
                raise OpenEoClientException("No refresh token given or found")

        authenticator = OidcRefreshTokenAuthenticator(
            client_info=client_info, refresh_token=refresh_token)
        return self._authenticate_oidc(authenticator, provider_id=provider_id)
Exemplo n.º 2
0
    def authenticate_oidc_refresh_token(
            self,
            client_id: str = None,
            refresh_token: str = None,
            client_secret: str = None,
            provider_id: str = None) -> 'Connection':
        """
        OpenId Connect Refresh Token
        """
        provider_id, client_info = self._get_oidc_provider_and_client_info(
            provider_id=provider_id,
            client_id=client_id,
            client_secret=client_secret,
            default_client_grant_types=[DefaultOidcClientGrant.REFRESH_TOKEN],
        )

        if refresh_token is None:
            refresh_token = self._get_refresh_token_store().get_refresh_token(
                issuer=client_info.provider.issuer,
                client_id=client_info.client_id)
            if refresh_token is None:
                raise OpenEoClientException("No refresh token given or found")

        authenticator = OidcRefreshTokenAuthenticator(
            client_info=client_info, refresh_token=refresh_token)
        return self._authenticate_oidc(authenticator, provider_id=provider_id)
Exemplo n.º 3
0
    def authenticate_oidc_refresh_token(
            self,
            client_id: str,
            refresh_token: str = None,
            client_secret: str = None,
            provider_id: str = None) -> 'Connection':
        """
        OpenId Connect Refresh Token

        WARNING: this API is in experimental phase
        """
        provider_id, provider = self._get_oidc_provider(provider_id)
        if refresh_token is None:
            store = RefreshTokenStore()
            # TODO: allow client_id/secret to be None and fetch it from config/cache?
            refresh_token = store.get(issuer=provider.issuer,
                                      client_id=client_id)
            if refresh_token is None:
                raise OpenEoClientException("No refresh token")

        client_info = OidcClientInfo(client_id=client_id,
                                     provider=provider,
                                     client_secret=client_secret)
        authenticator = OidcRefreshTokenAuthenticator(
            client_info=client_info, refresh_token=refresh_token)
        return self._authenticate_oidc(authenticator, provider_id=provider_id)
Exemplo n.º 4
0
def test_oidc_refresh_token_flow_no_secret(requests_mock, caplog):
    client_id = "myclient"
    refresh_token = "r3fr35h.d4.t0k3n.w1lly4"
    oidc_discovery_url = "http://oidc.test/.well-known/openid-configuration"
    oidc_mock = OidcMock(requests_mock=requests_mock,
                         expected_grant_type="refresh_token",
                         expected_client_id=client_id,
                         oidc_discovery_url=oidc_discovery_url,
                         expected_fields={
                             "scope": "openid",
                             "refresh_token": refresh_token
                         },
                         scopes_supported=["openid"])
    provider = OidcProviderInfo(discovery_url=oidc_discovery_url)
    authenticator = OidcRefreshTokenAuthenticator(client_info=OidcClientInfo(
        client_id=client_id, provider=provider),
                                                  refresh_token=refresh_token)
    tokens = authenticator.get_tokens()
    assert oidc_mock.state["access_token"] == tokens.access_token
    assert oidc_mock.state["refresh_token"] == tokens.refresh_token
Exemplo n.º 5
0
def test_oidc_refresh_token_invalid_token(requests_mock, caplog):
    client_id = "myclient"
    refresh_token = "wr0n9.t0k3n"
    oidc_discovery_url = "http://oidc.test/.well-known/openid-configuration"
    oidc_mock = OidcMock(requests_mock=requests_mock,
                         expected_grant_type="refresh_token",
                         expected_client_id=client_id,
                         oidc_discovery_url=oidc_discovery_url,
                         expected_fields={
                             "scope": "openid",
                             "refresh_token": "c0rr3ct.t0k3n"
                         },
                         scopes_supported=["openid"])
    provider = OidcProviderInfo(discovery_url=oidc_discovery_url)
    authenticator = OidcRefreshTokenAuthenticator(client_info=OidcClientInfo(
        client_id=client_id, provider=provider),
                                                  refresh_token=refresh_token)
    with pytest.raises(
            OidcException,
            match="Failed to retrieve access token.*invalid refresh token"):
        tokens = authenticator.get_tokens()
Exemplo n.º 6
0
    def authenticate_oidc(self,
                          provider_id: str = None,
                          client_id: Union[str, None] = None,
                          client_secret: Union[str, None] = None,
                          store_refresh_token: bool = True):
        """
        Do OpenID Connect authentication, first trying refresh tokens and falling back on device code flow.

        .. versionadded:: 0.6.0
        """
        provider_id, client_info = self._get_oidc_provider_and_client_info(
            provider_id=provider_id,
            client_id=client_id,
            client_secret=client_secret,
            default_client_grant_types=[
                DefaultOidcClientGrant.DEVICE_CODE_PKCE,
                DefaultOidcClientGrant.REFRESH_TOKEN
            ])

        # Try refresh token first.
        refresh_token = self._get_refresh_token_store().get_refresh_token(
            issuer=client_info.provider.issuer,
            client_id=client_info.client_id)
        if refresh_token:
            try:
                _log.info(
                    "Found refresh token: trying refresh token based authentication."
                )
                authenticator = OidcRefreshTokenAuthenticator(
                    client_info=client_info, refresh_token=refresh_token)
                con = self._authenticate_oidc(
                    authenticator,
                    provider_id=provider_id,
                    store_refresh_token=store_refresh_token)
                # TODO: pluggable/jupyter-aware display function?
                print("Authenticated using refresh token.")
                return con
            except OidcException as e:
                _log.info(
                    "Refresh token based authentication failed: {e}.".format(
                        e=e))

        # Fall back on device code flow
        # TODO: make it possible to do other fallback flows too?
        _log.info("Trying device code flow.")
        authenticator = OidcDeviceAuthenticator(client_info=client_info)
        con = self._authenticate_oidc(authenticator,
                                      provider_id=provider_id,
                                      store_refresh_token=store_refresh_token)
        print("Authenticated using device code flow.")
        return con