Skip to content
This repository has been archived by the owner on Mar 9, 2022. It is now read-only.

Replication Without Credentials in the URL

nutrixtech edited this page Aug 7, 2012 · 2 revisions

The following steps can be followed to have TouchDB-Android perform authenticated replications WITHOUT having to put the credentials into the URL.

  1. Implement your own HttpClientFactory which knows how to build HttpClient instances that can authenticate themselves.
  2. Register this implementation with TDServer as the default HttpClientFactory
  3. Start replication without credentials in the URL

Here is an example:

        // start TouchDB
        String filesDir = getContext().getFilesDir().getAbsolutePath();
        TDServer tdserver = new TDServer(filesDir);

        // register our own custom HttpClientFactory
        tdserver.setDefaultHttpClientFactory(new HttpClientFactory() {

            @Override
            public org.apache.http.client.HttpClient getHttpClient() {

                // start with a default http client
                DefaultHttpClient httpClient = new DefaultHttpClient();

                // create a credentials provider to store our credentials
                BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();

                // store our credentials
                AuthScope cloudantScope = new AuthScope("mschoch.cloudant.com", 5984);
                Credentials cloudantCredentials = new UsernamePasswordCredentials("mschoch", "notMyPassword");
                credsProvider.setCredentials(cloudantScope, cloudantCredentials);

                // set the credentials provider
                httpClient.setCredentialsProvider(credsProvider);

                // add an interceptor to sent the credentials preemptively
                HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() {

                    @Override
                    public void process(HttpRequest request,
                            HttpContext context) throws HttpException,
                            IOException {
                        AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
                        CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(
                                ClientContext.CREDS_PROVIDER);
                        HttpHost targetHost = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);

                        if (authState.getAuthScheme() == null) {
                            AuthScope authScope = new AuthScope(targetHost.getHostName(), targetHost.getPort());
                            Credentials creds = credsProvider.getCredentials(authScope);
                            authState.setCredentials(creds);
                            authState.setAuthScheme(new BasicScheme());
                        }
                    }
                };

                httpClient.addRequestInterceptor(preemptiveAuth, 0);

                return httpClient;
            }
        });

        // start TouchDB-Ektorp adapter
        HttpClient httpClient = new TouchDBHttpClient(tdserver);
        CouchDbInstance server = new StdCouchDbInstance(httpClient);

        // create a local database
        CouchDbConnector db = server.createConnector("testdb", true);

        // push this database to the test replication server
        ReplicationCommand pushCommand = new ReplicationCommand.Builder()
            .source("https://mschoch.cloudant.com/ektorp_replication_test")
            .target("testdb")
            .continuous(false)
            .build();

        ReplicationStatus status = server.replicate(pushCommand);

        ...

Things to watch out for:

  • AuthScope cloudantScope = new AuthScope("mschoch.cloudant.com", 5984); Make sure the url specified here is not prefixed by "https://" while trying to work under SSL.