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.hc.client5.testing.classic;
29
30 import java.io.IOException;
31
32 import org.apache.hc.client5.http.auth.StandardAuthScheme;
33 import org.apache.hc.client5.testing.auth.Authenticator;
34 import org.apache.hc.client5.testing.auth.BasicAuthTokenExtractor;
35 import org.apache.hc.core5.http.ClassicHttpRequest;
36 import org.apache.hc.core5.http.ClassicHttpResponse;
37 import org.apache.hc.core5.http.Header;
38 import org.apache.hc.core5.http.HttpException;
39 import org.apache.hc.core5.http.HttpHeaders;
40 import org.apache.hc.core5.http.HttpStatus;
41 import org.apache.hc.core5.http.io.HttpServerRequestHandler;
42 import org.apache.hc.core5.http.io.entity.EntityUtils;
43 import org.apache.hc.core5.http.io.entity.StringEntity;
44 import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
45 import org.apache.hc.core5.http.protocol.HttpContext;
46 import org.apache.hc.core5.net.URIAuthority;
47 import org.apache.hc.core5.util.Args;
48
49 public class AuthenticatingDecorator implements HttpServerRequestHandler {
50
51 private final HttpServerRequestHandler requestHandler;
52 private final Authenticator authenticator;
53 private final BasicAuthTokenExtractor authTokenExtractor;
54
55 public AuthenticatingDecorator(final HttpServerRequestHandler requestHandler, final Authenticator authenticator) {
56 this.requestHandler = Args.notNull(requestHandler, "Request handler");
57 this.authenticator = Args.notNull(authenticator, "Authenticator");
58 this.authTokenExtractor = new BasicAuthTokenExtractor();
59 }
60
61 protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
62 }
63
64 @Override
65 public void handle(
66 final ClassicHttpRequest request,
67 final ResponseTrigger responseTrigger,
68 final HttpContext context) throws HttpException, IOException {
69 final Header h = request.getFirstHeader(HttpHeaders.AUTHORIZATION);
70 final String challengeResponse = h != null ? authTokenExtractor.extract(h.getValue()) : null;
71
72 final URIAuthority authority = request.getAuthority();
73 final String requestUri = request.getRequestUri();
74
75 final boolean authenticated = authenticator.authenticate(authority, requestUri, challengeResponse);
76 final Header expect = request.getFirstHeader(HttpHeaders.EXPECT);
77 final boolean expectContinue = expect != null && "100-continue".equalsIgnoreCase(expect.getValue());
78
79 if (authenticated) {
80 if (expectContinue) {
81 responseTrigger.sendInformation(new BasicClassicHttpResponse(HttpStatus.SC_CONTINUE));
82 }
83 requestHandler.handle(request, responseTrigger, context);
84 } else {
85 final ClassicHttpResponse unauthorized = new BasicClassicHttpResponse(HttpStatus.SC_UNAUTHORIZED);
86 final String realm = authenticator.getRealm(authority, requestUri);
87 unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.BASIC + " realm=\"" + realm + "\"");
88 customizeUnauthorizedResponse(unauthorized);
89 if (unauthorized.getEntity() == null) {
90 unauthorized.setEntity(new StringEntity("Unauthorized"));
91 }
92 if (expectContinue || request.getEntity() == null) {
93
94 responseTrigger.submitResponse(unauthorized);
95
96 EntityUtils.consume(request.getEntity());
97 } else {
98
99 EntityUtils.consume(request.getEntity());
100
101 responseTrigger.submitResponse(unauthorized);
102 }
103 }
104 }
105
106 }