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 package org.apache.hc.client5.http.impl.auth;
28
29 import java.io.ByteArrayInputStream;
30 import java.io.ByteArrayOutputStream;
31 import java.io.ObjectInputStream;
32 import java.io.ObjectOutputStream;
33 import java.nio.charset.StandardCharsets;
34 import java.util.Base64;
35 import java.util.List;
36
37 import org.apache.hc.client5.http.auth.AuthChallenge;
38 import org.apache.hc.client5.http.auth.AuthScheme;
39 import org.apache.hc.client5.http.auth.AuthScope;
40 import org.apache.hc.client5.http.auth.AuthenticationException;
41 import org.apache.hc.client5.http.auth.ChallengeType;
42 import org.apache.hc.client5.http.auth.CredentialsProvider;
43 import org.apache.hc.client5.http.auth.StandardAuthScheme;
44 import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
45 import org.apache.hc.core5.http.HttpHost;
46 import org.apache.hc.core5.http.HttpRequest;
47 import org.apache.hc.core5.http.ParseException;
48 import org.apache.hc.core5.http.message.BasicHttpRequest;
49 import org.apache.hc.core5.http.message.ParserCursor;
50 import org.apache.hc.core5.util.CharArrayBuffer;
51 import org.junit.jupiter.api.Assertions;
52 import org.junit.jupiter.api.Test;
53
54
55
56
57 public class TestBasicScheme {
58 private static final Base64.Encoder BASE64_ENC = Base64.getEncoder();
59
60 private static AuthChallenge parse(final String s) throws ParseException {
61 final CharArrayBuffer buffer = new CharArrayBuffer(s.length());
62 buffer.append(s);
63 final ParserCursor cursor = new ParserCursor(0, buffer.length());
64 final List<AuthChallenge> authChallenges = AuthChallengeParser.INSTANCE.parse(ChallengeType.TARGET, buffer, cursor);
65 Assertions.assertEquals(1, authChallenges.size());
66 return authChallenges.get(0);
67 }
68
69 @Test
70 public void testBasicAuthenticationEmptyChallenge() throws Exception {
71 final String challenge = StandardAuthScheme.BASIC;
72 final AuthChallenge authChallenge = parse(challenge);
73 final AuthScheme authscheme = new BasicScheme();
74 authscheme.processChallenge(authChallenge, null);
75 Assertions.assertNull(authscheme.getRealm());
76 }
77
78 @Test
79 public void testBasicAuthentication() throws Exception {
80 final AuthChallenge authChallenge = parse("Basic realm=\"test\"");
81
82 final BasicScheme authscheme = new BasicScheme();
83 authscheme.processChallenge(authChallenge, null);
84
85 final HttpHost host = new HttpHost("somehost", 80);
86 final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
87 .add(new AuthScope(host, "test", null), "testuser", "testpass".toCharArray())
88 .build();
89
90 final HttpRequest request = new BasicHttpRequest("GET", "/");
91 Assertions.assertTrue(authscheme.isResponseReady(host, credentialsProvider, null));
92 final String authResponse = authscheme.generateAuthResponse(host, request, null);
93
94 final byte[] testCreds = "testuser:testpass".getBytes(StandardCharsets.US_ASCII);
95
96 final String expected = "Basic " + BASE64_ENC.encodeToString(testCreds);
97
98 Assertions.assertEquals(expected, authResponse);
99 Assertions.assertEquals("test", authscheme.getRealm());
100 Assertions.assertTrue(authscheme.isChallengeComplete());
101 Assertions.assertFalse(authscheme.isConnectionBased());
102 }
103
104 static final String TEST_UTF8_PASSWORD = "123\u00A3";
105
106 @Test
107 public void testBasicAuthenticationDefaultCharsetASCII() throws Exception {
108 final HttpHost host = new HttpHost("somehost", 80);
109 final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("test", TEST_UTF8_PASSWORD.toCharArray());
110 final BasicScheme authscheme = new BasicScheme(StandardCharsets.US_ASCII);
111 final HttpRequest request = new BasicHttpRequest("GET", "/");
112 authscheme.initPreemptive(creds);
113 final String authResponse = authscheme.generateAuthResponse(host, request, null);
114 Assertions.assertEquals("Basic dGVzdDoxMjM/", authResponse);
115 }
116
117 @Test
118 public void testBasicAuthenticationDefaultCharsetISO88591() throws Exception {
119 final HttpHost host = new HttpHost("somehost", 80);
120 final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("test", TEST_UTF8_PASSWORD.toCharArray());
121 final BasicScheme authscheme = new BasicScheme(StandardCharsets.ISO_8859_1);
122 final HttpRequest request = new BasicHttpRequest("GET", "/");
123 authscheme.initPreemptive(creds);
124 final String authResponse = authscheme.generateAuthResponse(host, request, null);
125 Assertions.assertEquals("Basic dGVzdDoxMjOj", authResponse);
126 }
127
128 @Test
129 public void testBasicAuthenticationDefaultCharsetUTF8() throws Exception {
130 final HttpHost host = new HttpHost("somehost", 80);
131 final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("test", TEST_UTF8_PASSWORD.toCharArray());
132 final BasicScheme authscheme = new BasicScheme(StandardCharsets.UTF_8);
133 final HttpRequest request = new BasicHttpRequest("GET", "/");
134 authscheme.initPreemptive(creds);
135 final String authResponse = authscheme.generateAuthResponse(host, request, null);
136 Assertions.assertEquals("Basic dGVzdDoxMjPCow==", authResponse);
137 }
138
139 @Test
140 public void testBasicAuthenticationWithCharset() throws Exception {
141 final AuthChallenge authChallenge = parse("Basic realm=\"test\", charset=\"utf-8\"");
142
143 final BasicScheme authscheme = new BasicScheme();
144 authscheme.processChallenge(authChallenge, null);
145
146 final HttpHost host = new HttpHost("somehost", 80);
147 final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
148 .add(new AuthScope(host, "test", null), "test", TEST_UTF8_PASSWORD.toCharArray())
149 .build();
150
151 final HttpRequest request = new BasicHttpRequest("GET", "/");
152 Assertions.assertTrue(authscheme.isResponseReady(host, credentialsProvider, null));
153 final String authResponse = authscheme.generateAuthResponse(host, request, null);
154 Assertions.assertEquals("Basic dGVzdDoxMjPCow==", authResponse);
155 Assertions.assertEquals("test", authscheme.getRealm());
156 Assertions.assertTrue(authscheme.isChallengeComplete());
157 Assertions.assertFalse(authscheme.isConnectionBased());
158 }
159
160 @Test
161 public void testSerialization() throws Exception {
162 final AuthChallenge authChallenge = parse("Basic realm=\"test\"");
163
164 final BasicScheme basicScheme = new BasicScheme();
165 basicScheme.processChallenge(authChallenge, null);
166
167 final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
168 final ObjectOutputStream out = new ObjectOutputStream(buffer);
169 out.writeObject(basicScheme);
170 out.flush();
171 final byte[] raw = buffer.toByteArray();
172 final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(raw));
173 final BasicScheme authScheme = (BasicScheme) in.readObject();
174
175 Assertions.assertEquals(basicScheme.getName(), authScheme.getName());
176 Assertions.assertEquals(basicScheme.getRealm(), authScheme.getRealm());
177 Assertions.assertEquals(basicScheme.isChallengeComplete(), authScheme.isChallengeComplete());
178 }
179
180 @Test
181 public void testSerializationUnchallenged() throws Exception {
182 final BasicScheme basicScheme = new BasicScheme();
183
184 final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
185 final ObjectOutputStream out = new ObjectOutputStream(buffer);
186 out.writeObject(basicScheme);
187 out.flush();
188 final byte[] raw = buffer.toByteArray();
189 final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(raw));
190 final BasicScheme authScheme = (BasicScheme) in.readObject();
191
192 Assertions.assertEquals(basicScheme.getName(), authScheme.getName());
193 Assertions.assertEquals(basicScheme.getRealm(), authScheme.getRealm());
194 Assertions.assertEquals(basicScheme.isChallengeComplete(), authScheme.isChallengeComplete());
195 }
196
197 @Test
198 public void testBasicAuthenticationUserCredentialsMissing() throws Exception {
199 final BasicScheme authscheme = new BasicScheme();
200 final HttpHost host = new HttpHost("somehost", 80);
201 final HttpRequest request = new BasicHttpRequest("GET", "/");
202 Assertions.assertThrows(AuthenticationException.class, () -> authscheme.generateAuthResponse(host, request, null));
203 }
204
205 @Test
206 public void testBasicAuthenticationUsernameWithBlank() throws Exception {
207 final BasicScheme authscheme = new BasicScheme();
208 final HttpHost host = new HttpHost("somehost", 80);
209 final HttpRequest request = new BasicHttpRequest("GET", "/");
210 authscheme.initPreemptive(new UsernamePasswordCredentials("blah blah", null));
211 authscheme.generateAuthResponse(host, request, null);
212 }
213
214 @Test
215 public void testBasicAuthenticationUsernameWithTab() throws Exception {
216 final BasicScheme authscheme = new BasicScheme();
217 final HttpHost host = new HttpHost("somehost", 80);
218 final HttpRequest request = new BasicHttpRequest("GET", "/");
219 authscheme.initPreemptive(new UsernamePasswordCredentials("blah\tblah", null));
220 Assertions.assertThrows(AuthenticationException.class, () -> authscheme.generateAuthResponse(host, request, null));
221 }
222
223 @Test
224 public void testBasicAuthenticationUsernameWithColon() throws Exception {
225 final BasicScheme authscheme = new BasicScheme();
226 final HttpHost host = new HttpHost("somehost", 80);
227 final HttpRequest request = new BasicHttpRequest("GET", "/");
228 authscheme.initPreemptive(new UsernamePasswordCredentials("blah:blah", null));
229 Assertions.assertThrows(AuthenticationException.class, () -> authscheme.generateAuthResponse(host, request, null));
230 }
231
232 }