1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.http.client.protocol;
29
30 import java.io.IOException;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.http.HttpException;
35 import org.apache.http.HttpHost;
36 import org.apache.http.HttpRequest;
37 import org.apache.http.HttpRequestInterceptor;
38 import org.apache.http.annotation.Immutable;
39 import org.apache.http.auth.AuthProtocolState;
40 import org.apache.http.auth.AuthScheme;
41 import org.apache.http.auth.AuthScope;
42 import org.apache.http.auth.AuthState;
43 import org.apache.http.auth.Credentials;
44 import org.apache.http.client.AuthCache;
45 import org.apache.http.client.CredentialsProvider;
46 import org.apache.http.conn.routing.RouteInfo;
47 import org.apache.http.protocol.HttpContext;
48 import org.apache.http.util.Args;
49
50
51
52
53
54
55
56
57 @Immutable
58 public class RequestAuthCache implements HttpRequestInterceptor {
59
60 private final Log log = LogFactory.getLog(getClass());
61
62 public RequestAuthCache() {
63 super();
64 }
65
66 public void process(final HttpRequest request, final HttpContext context)
67 throws HttpException, IOException {
68 Args.notNull(request, "HTTP request");
69 Args.notNull(context, "HTTP context");
70
71 final HttpClientContext clientContext = HttpClientContext.adapt(context);
72
73 final AuthCache authCache = clientContext.getAuthCache();
74 if (authCache == null) {
75 this.log.debug("Auth cache not set in the context");
76 return;
77 }
78
79 final CredentialsProvider credsProvider = clientContext.getCredentialsProvider();
80 if (credsProvider == null) {
81 this.log.debug("Credentials provider not set in the context");
82 return;
83 }
84
85 final RouteInfo route = clientContext.getHttpRoute();
86 HttpHost target = clientContext.getTargetHost();
87 if (target.getPort() < 0) {
88 target = new HttpHost(
89 target.getHostName(),
90 route.getTargetHost().getPort(),
91 target.getSchemeName());
92 }
93
94 final AuthState targetState = clientContext.getTargetAuthState();
95 if (targetState != null && targetState.getState() == AuthProtocolState.UNCHALLENGED) {
96 final AuthScheme authScheme = authCache.get(target);
97 if (authScheme != null) {
98 doPreemptiveAuth(target, authScheme, targetState, credsProvider);
99 }
100 }
101
102 final HttpHost proxy = route.getProxyHost();
103 final AuthState proxyState = clientContext.getProxyAuthState();
104 if (proxy != null && proxyState != null && proxyState.getState() == AuthProtocolState.UNCHALLENGED) {
105 final AuthScheme authScheme = authCache.get(proxy);
106 if (authScheme != null) {
107 doPreemptiveAuth(proxy, authScheme, proxyState, credsProvider);
108 }
109 }
110 }
111
112 private void doPreemptiveAuth(
113 final HttpHost host,
114 final AuthScheme authScheme,
115 final AuthState authState,
116 final CredentialsProvider credsProvider) {
117 final String schemeName = authScheme.getSchemeName();
118 if (this.log.isDebugEnabled()) {
119 this.log.debug("Re-using cached '" + schemeName + "' auth scheme for " + host);
120 }
121
122 final AuthScope authScope = new AuthScope(host, AuthScope.ANY_REALM, schemeName);
123 final Credentials creds = credsProvider.getCredentials(authScope);
124
125 if (creds != null) {
126 if ("BASIC".equalsIgnoreCase(authScheme.getSchemeName())) {
127 authState.setState(AuthProtocolState.CHALLENGED);
128 } else {
129 authState.setState(AuthProtocolState.SUCCESS);
130 }
131 authState.update(authScheme, creds);
132 } else {
133 this.log.debug("No credentials for preemptive authentication");
134 }
135 }
136
137 }