|
108 | 108 | import java.util.Map;
|
109 | 109 | import java.util.UUID;
|
110 | 110 | import java.util.concurrent.CountDownLatch;
|
| 111 | +import java.util.concurrent.atomic.AtomicBoolean; |
111 | 112 | import java.util.concurrent.atomic.AtomicReference;
|
112 | 113 |
|
113 | 114 | import javax.crypto.SecretKey;
|
@@ -968,6 +969,53 @@ public void testHandleUserinfoResponseFailure() throws Exception {
|
968 | 969 | );
|
969 | 970 | }
|
970 | 971 |
|
| 972 | + public void testHandleUserinfoValidationFailsOnNotMatchingSubject() throws Exception { |
| 973 | + final ProtocolVersion httpVersion = randomFrom(HttpVersion.HTTP_0_9, HttpVersion.HTTP_1_0, HttpVersion.HTTP_1_1); |
| 974 | + final HttpResponse response = new BasicHttpResponse(new BasicStatusLine(httpVersion, RestStatus.OK.getStatus(), "OK")); |
| 975 | + |
| 976 | + final String sub = randomAlphaOfLengthBetween(4, 36); |
| 977 | + final String inf = randomAlphaOfLength(12); |
| 978 | + final JWTClaimsSet infoClaims = new JWTClaimsSet.Builder().subject("it-is-a-different-subject").claim("inf", inf).build(); |
| 979 | + final StringEntity entity = new StringEntity(infoClaims.toString(), ContentType.APPLICATION_JSON); |
| 980 | + if (randomBoolean()) { |
| 981 | + entity.setContentEncoding( |
| 982 | + randomFrom(StandardCharsets.UTF_8.name(), StandardCharsets.UTF_16.name(), StandardCharsets.US_ASCII.name()) |
| 983 | + ); |
| 984 | + } |
| 985 | + response.setEntity(entity); |
| 986 | + |
| 987 | + final String idx = randomAlphaOfLength(8); |
| 988 | + final JWTClaimsSet idClaims = new JWTClaimsSet.Builder().subject(sub).claim("idx", idx).build(); |
| 989 | + final AtomicBoolean listenerCalled = new AtomicBoolean(false); |
| 990 | + final PlainActionFuture<JWTClaimsSet> future = new PlainActionFuture<>() { |
| 991 | + |
| 992 | + @Override |
| 993 | + public void onResponse(JWTClaimsSet result) { |
| 994 | + assertTrue("listener called more than once", listenerCalled.compareAndSet(false, true)); |
| 995 | + super.onResponse(result); |
| 996 | + } |
| 997 | + |
| 998 | + @Override |
| 999 | + public void onFailure(Exception e) { |
| 1000 | + assertTrue("listener called more than once", listenerCalled.compareAndSet(false, true)); |
| 1001 | + super.onFailure(e); |
| 1002 | + } |
| 1003 | + }; |
| 1004 | + |
| 1005 | + this.authenticator = buildAuthenticator(); |
| 1006 | + OpenIdConnectAuthenticator.handleUserinfoResponse(response, idClaims, future); |
| 1007 | + var e = expectThrows(ElasticsearchSecurityException.class, future::actionGet); |
| 1008 | + |
| 1009 | + assertThat( |
| 1010 | + e.getMessage(), |
| 1011 | + equalTo( |
| 1012 | + "Userinfo Response is not valid as it is for subject [it-is-a-different-subject] while the ID Token was for subject [" |
| 1013 | + + sub |
| 1014 | + + "]" |
| 1015 | + ) |
| 1016 | + ); |
| 1017 | + } |
| 1018 | + |
971 | 1019 | public void testHandleTokenResponseNullContentType() {
|
972 | 1020 | final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, RestStatus.OK.getStatus(), "");
|
973 | 1021 | final StringEntity entity = new StringEntity("", (ContentType) null);
|
|
0 commit comments