diff --git a/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/ClientPreemptiveDigestAuthentication.java b/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/ClientPreemptiveDigestAuthentication.java
new file mode 100644
index 0000000000..5887d2dcab
--- /dev/null
+++ b/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/ClientPreemptiveDigestAuthentication.java
@@ -0,0 +1,70 @@
+package org.baeldung.client;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.AuthCache;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.impl.auth.DigestScheme;
+import org.apache.http.impl.client.BasicAuthCache;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.util.EntityUtils;
+
+/**
+ * An example of HttpClient can be customized to authenticate
+ * preemptively using DIGEST scheme.
+ *
+ * Generally, preemptive authentication can be considered less
+ * secure than a response to an authentication challenge
+ * and therefore discouraged.
+ */
+public class ClientPreemptiveDigestAuthentication {
+
+ public static void main(final String[] args) throws Exception {
+ final HttpHost targetHost = new HttpHost("localhost", 8080, "http");
+
+ final DefaultHttpClient httpclient = new DefaultHttpClient();
+ try {
+ httpclient.getCredentialsProvider().setCredentials(new AuthScope(targetHost.getHostName(), targetHost.getPort()), new UsernamePasswordCredentials("user1", "user1Pass"));
+
+ // Create AuthCache instance
+ final AuthCache authCache = new BasicAuthCache();
+ // Generate DIGEST scheme object, initialize it and add it to the local auth cache
+ final DigestScheme digestAuth = new DigestScheme();
+ // Suppose we already know the realm name
+ digestAuth.overrideParamter("realm", "Custom Realm Name");
+
+ // digestAuth.overrideParamter("nonce", "whatever");
+ authCache.put(targetHost, digestAuth);
+
+ // Add AuthCache to the execution context
+ final BasicHttpContext localcontext = new BasicHttpContext();
+ localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
+
+ final HttpGet httpget = new HttpGet("http://localhost:8080/spring-security-rest-digest-auth/api/foos/1");
+
+ System.out.println("executing request: " + httpget.getRequestLine());
+ System.out.println("to target: " + targetHost);
+
+ for (int i = 0; i < 3; i++) {
+ final HttpResponse response = httpclient.execute(targetHost, httpget, localcontext);
+ final HttpEntity entity = response.getEntity();
+
+ System.out.println("----------------------------------------");
+ System.out.println(response.getStatusLine());
+ if (entity != null) {
+ System.out.println("Response content length: " + entity.getContentLength());
+ }
+ EntityUtils.consume(entity);
+ }
+ } finally {
+ // When HttpClient instance is no longer needed, shut down the connection manager to ensure immediate deallocation of all system resources
+ httpclient.getConnectionManager().shutdown();
+ }
+ }
+
+}
diff --git a/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryBasicAuth.java b/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryDigestAuth.java
similarity index 61%
rename from spring-security-rest-digest-auth/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryBasicAuth.java
rename to spring-security-rest-digest-auth/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryDigestAuth.java
index 5f808413ce..d9d89db224 100644
--- a/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryBasicAuth.java
+++ b/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/HttpComponentsClientHttpRequestFactoryDigestAuth.java
@@ -5,17 +5,17 @@ import java.net.URI;
import org.apache.http.HttpHost;
import org.apache.http.client.AuthCache;
import org.apache.http.client.protocol.ClientContext;
-import org.apache.http.impl.auth.BasicScheme;
+import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
-public class HttpComponentsClientHttpRequestFactoryBasicAuth extends HttpComponentsClientHttpRequestFactory {
+public class HttpComponentsClientHttpRequestFactoryDigestAuth extends HttpComponentsClientHttpRequestFactory {
HttpHost host;
- public HttpComponentsClientHttpRequestFactoryBasicAuth(final HttpHost host) {
+ public HttpComponentsClientHttpRequestFactoryDigestAuth(final HttpHost host) {
super();
this.host = host;
}
@@ -30,9 +30,14 @@ public class HttpComponentsClientHttpRequestFactoryBasicAuth extends HttpCompone
private HttpContext createHttpContext() {
// Create AuthCache instance
final AuthCache authCache = new BasicAuthCache();
- // Generate BASIC scheme object and add it to the local auth cache
- final BasicScheme basicAuth = new BasicScheme();
- authCache.put(host, basicAuth);
+ // Generate DIGEST scheme object, initialize it and add it to the local auth cache
+ final DigestScheme digestAuth = new DigestScheme();
+ // If we already know the realm name
+ digestAuth.overrideParamter("realm", "Custom Realm Name");
+
+ // digestAuth.overrideParamter("nonce", "MTM3NTU2OTU4MDAwNzoyYWI5YTQ5MTlhNzc5N2UxMGM5M2Y5M2ViOTc4ZmVhNg==");
+ authCache.put(host, digestAuth);
+
// Add AuthCache to the execution context
final BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
diff --git a/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/RestTemplateFactory.java b/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/RestTemplateFactory.java
deleted file mode 100644
index e8df87524c..0000000000
--- a/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/RestTemplateFactory.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.baeldung.client;
-
-import org.apache.http.HttpHost;
-import org.apache.http.client.HttpClient;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
-
-@Component
-public class RestTemplateFactory implements FactoryBean, InitializingBean {
- private RestTemplate restTemplate;
-
- public RestTemplateFactory() {
- super();
- }
-
- // API
-
- @Override
- public RestTemplate getObject() {
- return restTemplate;
- }
-
- @Override
- public Class getObjectType() {
- return RestTemplate.class;
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
-
- @Override
- public void afterPropertiesSet() {
- final HttpHost host = new HttpHost("localhost", 8080, "http");
- final HttpComponentsClientHttpRequestFactoryBasicAuth requestFactory = new HttpComponentsClientHttpRequestFactoryBasicAuth(host);
- restTemplate = new RestTemplate(requestFactory);
-
- final int timeout = 5;
- final HttpClient httpClient = requestFactory.getHttpClient();
- // - note: timeout via raw String parameters
- // httpClient.getParams().setParameter("http.connection.timeout", timeout * 1000);
- // httpClient.getParams().setParameter("http.socket.timeout", timeout * 1000);
-
- // httpClient.getParams().setParameter("http.connection-manager.timeout", new Long(timeout * 1000));
- // httpClient.getParams().setParameter("http.protocol.head-body-timeout", timeout * 1000);
-
- // - note: timeout via the API
- final HttpParams httpParams = httpClient.getParams();
- HttpConnectionParams.setConnectionTimeout(httpParams, timeout * 1000); // http.connection.timeout
- HttpConnectionParams.setSoTimeout(httpParams, timeout * 1000); // http.socket.timeout
- }
-
-}
\ No newline at end of file
diff --git a/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/spring/ClientConfig.java b/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/spring/ClientConfig.java
index 73e602855c..615be8f524 100644
--- a/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/spring/ClientConfig.java
+++ b/spring-security-rest-digest-auth/src/main/java/org/baeldung/client/spring/ClientConfig.java
@@ -1,10 +1,16 @@
package org.baeldung.client.spring;
-import org.springframework.context.annotation.ComponentScan;
+import org.apache.http.HttpHost;
+import org.apache.http.client.HttpClient;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.baeldung.client.HttpComponentsClientHttpRequestFactoryDigestAuth;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
@Configuration
-@ComponentScan("org.baeldung.client")
public class ClientConfig {
public ClientConfig() {
@@ -13,4 +19,33 @@ public class ClientConfig {
// beans
+ @Bean
+ public RestTemplate restTemplate() {
+ final HttpHost host = new HttpHost("localhost", 8080, "http");
+ final HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactoryDigestAuth(host);
+ final RestTemplate restTemplate = new RestTemplate(requestFactory);
+
+ final int timeout = 5;
+ configureTimeouts(requestFactory, timeout);
+
+ return restTemplate;
+ }
+
+ // util
+
+ private final void configureTimeouts(final HttpComponentsClientHttpRequestFactory requestFactory, final int timeout) {
+ final HttpClient httpClient = requestFactory.getHttpClient();
+ // - note: timeout via raw String parameters
+ // httpClient.getParams().setParameter("http.connection.timeout", timeout * 1000);
+ // httpClient.getParams().setParameter("http.socket.timeout", timeout * 1000);
+
+ // httpClient.getParams().setParameter("http.connection-manager.timeout", new Long(timeout * 1000));
+ // httpClient.getParams().setParameter("http.protocol.head-body-timeout", timeout * 1000);
+
+ // - note: timeout via the API
+ final HttpParams httpParams = httpClient.getParams();
+ HttpConnectionParams.setConnectionTimeout(httpParams, timeout * 1000); // http.connection.timeout
+ HttpConnectionParams.setSoTimeout(httpParams, timeout * 1000); // http.socket.timeout
+ }
+
}
\ No newline at end of file
diff --git a/spring-security-rest-digest-auth/src/main/resources/webSecurityConfig.xml b/spring-security-rest-digest-auth/src/main/resources/webSecurityConfig.xml
index ba3b0f9017..2dbcf84eee 100644
--- a/spring-security-rest-digest-auth/src/main/resources/webSecurityConfig.xml
+++ b/spring-security-rest-digest-auth/src/main/resources/webSecurityConfig.xml
@@ -11,7 +11,7 @@
-
+
diff --git a/spring-security-rest-digest-auth/src/test/java/org/baeldung/client/ClientLiveTest.java b/spring-security-rest-digest-auth/src/test/java/org/baeldung/client/ClientLiveTest.java
index f63537ae6b..9ab6854f61 100644
--- a/spring-security-rest-digest-auth/src/test/java/org/baeldung/client/ClientLiveTest.java
+++ b/spring-security-rest-digest-auth/src/test/java/org/baeldung/client/ClientLiveTest.java
@@ -29,9 +29,10 @@ public class ClientLiveTest {
public final void whenSecuredRestApiIsConsumed_then200OK() {
final HttpComponentsClientHttpRequestFactory requestFactory = (HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory();
final DefaultHttpClient httpClient = (DefaultHttpClient) requestFactory.getHttpClient();
- httpClient.getCredentialsProvider().setCredentials(new AuthScope("localhost", 8080, AuthScope.ANY_REALM), new UsernamePasswordCredentials("user", "userPass"));
+ httpClient.getCredentialsProvider().setCredentials(new AuthScope("localhost", 8080, AuthScope.ANY_REALM), new UsernamePasswordCredentials("user1", "user1Pass"));
- final ResponseEntity responseEntity = restTemplate.exchange("http://localhost:8080/spring-security-rest-digest-auth/api/foos/1", HttpMethod.GET, null, Foo.class);
+ final String uri = "http://localhost:8080/spring-security-rest-digest-auth/api/foos/1";
+ final ResponseEntity responseEntity = restTemplate.exchange(uri, HttpMethod.GET, null, Foo.class);
System.out.println(responseEntity.getStatusCode());
}
diff --git a/spring-security-rest-template/README.md b/spring-security-rest-template/README.md
index 9030dffbd7..a857ddc778 100644
--- a/spring-security-rest-template/README.md
+++ b/spring-security-rest-template/README.md
@@ -6,3 +6,5 @@
### Relevant Articles:
- [RestTemplate with Basic Authentication in Spring](http://www.baeldung.com/2012/04/16/how-to-use-resttemplate-with-basic-authentication-in-spring-3-1)
- [HttpClient Timeout](http://www.baeldung.com/httpclient-timeout)
+
+TODO: rename to: spring-security-rest-basic-auth
\ No newline at end of file