Skip to content

Commit

Permalink
OIDC UserInfo Endpoint
Browse files Browse the repository at this point in the history
Signed-off-by: Stephen Crawford <[email protected]>
  • Loading branch information
stephen-crawford committed Aug 16, 2024
1 parent 444deee commit 5aeb90e
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public class OpenIdConstants {
public static final String APPLICATION_JSON = "application/json";
public static final String APPLICATION_JWT = "application/jwt";
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String USERINFO_ENCRYPTED_RESPONSE_ALG = "userinfo_encrypted_response_alg";
public static final String CLIENT_ID = "client_id";
public static final String ISSUER_ID_URL = "issuer_id_url";
public static final String SUB_CLAIM = "sub";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import org.opensearch.security.user.AuthCredentials;
import org.opensearch.security.util.FakeRestRequest;

import static com.amazon.dlic.auth.http.jwt.keybyoidc.OpenIdConstants.CLIENT_ID;
import static com.amazon.dlic.auth.http.jwt.keybyoidc.OpenIdConstants.ISSUER_ID_URL;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

Expand Down Expand Up @@ -413,4 +415,221 @@ public void testPeculiarJsonEscaping() throws Exception {
assertThat(creds.getAttributes().size(), is(4));
}

@Test
public void userinfoEndpointReturnsJwtWithAllRequirementsTest() throws Exception {
Settings settings = Settings.builder()
.put("openid_connect_url", mockIdpServer.getDiscoverUri())
.put("userinfo_endpoint", mockIdpServer.getUserinfoUri())
.put(CLIENT_ID, "testClient")
.put(ISSUER_ID_URL, "http://www.example.com")
.put("required_issuer", TestJwts.TEST_ISSUER)
.put("required_audience", TestJwts.TEST_AUDIENCE + ",another_audience")
.build();

HTTPOpenIdAuthenticator openIdAuthenticator = new HTTPOpenIdAuthenticator(settings, null);

AuthCredentials creds = openIdAuthenticator.extractCredentials(
new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()).asSecurityRequest(),
null
);

Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is(TestJwts.MCCOY_SUBJECT));
assertThat(creds.getAttributes().get("attr.jwt.aud"), is(List.of(TestJwts.TEST_AUDIENCE).toString()));
assertThat(creds.getBackendRoles().size(), is(0));
assertThat(creds.getAttributes().size(), is(4));
}

@Test
public void userinfoEndpointReturnsJwtMissingIssuerTest() throws Exception {
Settings settings = Settings.builder()
.put("openid_connect_url", mockIdpServer.getDiscoverUri())
.put("userinfo_endpoint", mockIdpServer.getUserinfoUri())
.put(CLIENT_ID, "testClient")
.put(ISSUER_ID_URL, "http://www.example.com")
.put("required_issuer", TestJwts.TEST_ISSUER)
.put("required_audience", TestJwts.TEST_AUDIENCE + ",another_audience")
.build();

HTTPOpenIdAuthenticator openIdAuthenticator = new HTTPOpenIdAuthenticator(settings, null);

AuthCredentials creds = openIdAuthenticator.extractCredentials(
new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()).asSecurityRequest(),
null
);

Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is(TestJwts.MCCOY_SUBJECT));
assertThat(creds.getAttributes().get("attr.jwt.aud"), is(List.of(TestJwts.TEST_AUDIENCE).toString()));
assertThat(creds.getBackendRoles().size(), is(0));
assertThat(creds.getAttributes().size(), is(4));
}

@Test
public void userinfoEndpointReturnsJwtMissingAudienceTest() throws Exception {
Settings settings = Settings.builder()
.put("openid_connect_url", mockIdpServer.getDiscoverUri())
.put("userinfo_endpoint", mockIdpServer.getUserinfoUri())
.put(CLIENT_ID, "testClient")
.put(ISSUER_ID_URL, "http://www.example.com")
.put("required_issuer", TestJwts.TEST_ISSUER)
.put("required_audience", TestJwts.TEST_AUDIENCE + ",another_audience")
.build();

HTTPOpenIdAuthenticator openIdAuthenticator = new HTTPOpenIdAuthenticator(settings, null);

AuthCredentials creds = openIdAuthenticator.extractCredentials(
new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()).asSecurityRequest(),
null
);

Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is(TestJwts.MCCOY_SUBJECT));
assertThat(creds.getAttributes().get("attr.jwt.aud"), is(List.of(TestJwts.TEST_AUDIENCE).toString()));
assertThat(creds.getBackendRoles().size(), is(0));
assertThat(creds.getAttributes().size(), is(4));
}

@Test
public void userinfoEndpointReturnsJwtMismatchedSubTest() throws Exception {
Settings settings = Settings.builder()
.put("openid_connect_url", mockIdpServer.getDiscoverUri())
.put("userinfo_endpoint", mockIdpServer.getUserinfoUri())
.put(CLIENT_ID, "testClient")
.put(ISSUER_ID_URL, "http://www.example.com")
.put("required_issuer", TestJwts.TEST_ISSUER)
.put("required_audience", TestJwts.TEST_AUDIENCE + ",another_audience")
.build();

HTTPOpenIdAuthenticator openIdAuthenticator = new HTTPOpenIdAuthenticator(settings, null);

AuthCredentials creds = openIdAuthenticator.extractCredentials(
new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()).asSecurityRequest(),
null
);

Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is(TestJwts.MCCOY_SUBJECT));
assertThat(creds.getAttributes().get("attr.jwt.aud"), is(List.of(TestJwts.TEST_AUDIENCE).toString()));
assertThat(creds.getBackendRoles().size(), is(0));
assertThat(creds.getAttributes().size(), is(4));
}

@Test
public void userinfoEndpointReturnsJwtInvalidAlgTest() throws Exception {
Settings settings = Settings.builder()
.put("openid_connect_url", mockIdpServer.getDiscoverUri())
.put("userinfo_endpoint", mockIdpServer.getUserinfoUri())
.put(CLIENT_ID, "testClient")
.put(ISSUER_ID_URL, "http://www.example.com")
.put("required_issuer", TestJwts.TEST_ISSUER)
.put("required_audience", TestJwts.TEST_AUDIENCE + ",another_audience")
.build();

HTTPOpenIdAuthenticator openIdAuthenticator = new HTTPOpenIdAuthenticator(settings, null);

AuthCredentials creds = openIdAuthenticator.extractCredentials(
new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()).asSecurityRequest(),
null
);

Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is(TestJwts.MCCOY_SUBJECT));
assertThat(creds.getAttributes().get("attr.jwt.aud"), is(List.of(TestJwts.TEST_AUDIENCE).toString()));
assertThat(creds.getBackendRoles().size(), is(0));
assertThat(creds.getAttributes().size(), is(4));
}

@Test
public void userinfoEndpointReturnsJsonWithAllRequirementsTest() throws Exception {
Settings settings = Settings.builder()
.put("openid_connect_url", mockIdpServer.getDiscoverUri())
.put("userinfo_endpoint", mockIdpServer.getUserinfoUri())
.put("required_issuer", TestJwts.TEST_ISSUER)
.put("required_audience", TestJwts.TEST_AUDIENCE + ",another_audience")
.build();

HTTPOpenIdAuthenticator openIdAuthenticator = new HTTPOpenIdAuthenticator(settings, null);

AuthCredentials creds = openIdAuthenticator.extractCredentials(
new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()).asSecurityRequest(),
null
);

Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is(TestJwts.MCCOY_SUBJECT));
assertThat(creds.getAttributes().get("attr.jwt.aud"), is(List.of(TestJwts.TEST_AUDIENCE).toString()));
assertThat(creds.getBackendRoles().size(), is(0));
assertThat(creds.getAttributes().size(), is(4));
}

@Test
public void userinfoEndpointReturnsJsonMismatchedSubTest() throws Exception {
Settings settings = Settings.builder()
.put("openid_connect_url", mockIdpServer.getDiscoverUri())
.put("userinfo_endpoint", mockIdpServer.getUserinfoUri())
.put("required_issuer", TestJwts.TEST_ISSUER)
.put("required_audience", TestJwts.TEST_AUDIENCE + ",another_audience")
.build();

HTTPOpenIdAuthenticator openIdAuthenticator = new HTTPOpenIdAuthenticator(settings, null);

AuthCredentials creds = openIdAuthenticator.extractCredentials(
new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()).asSecurityRequest(),
null
);

Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is(TestJwts.MCCOY_SUBJECT));
assertThat(creds.getAttributes().get("attr.jwt.aud"), is(List.of(TestJwts.TEST_AUDIENCE).toString()));
assertThat(creds.getBackendRoles().size(), is(0));
assertThat(creds.getAttributes().size(), is(4));
}

@Test
public void userinfoEndpointReturnsResponseNot2xxTest() throws Exception {
Settings settings = Settings.builder()
.put("openid_connect_url", mockIdpServer.getDiscoverUri())
.put("userinfo_endpoint", mockIdpServer.getUserinfoUri())
.put("required_issuer", TestJwts.TEST_ISSUER)
.put("required_audience", TestJwts.TEST_AUDIENCE + ",another_audience")
.build();

HTTPOpenIdAuthenticator openIdAuthenticator = new HTTPOpenIdAuthenticator(settings, null);

AuthCredentials creds = openIdAuthenticator.extractCredentials(
new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()).asSecurityRequest(),
null
);

Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is(TestJwts.MCCOY_SUBJECT));
assertThat(creds.getAttributes().get("attr.jwt.aud"), is(List.of(TestJwts.TEST_AUDIENCE).toString()));
assertThat(creds.getBackendRoles().size(), is(0));
assertThat(creds.getAttributes().size(), is(4));
}

@Test
public void userinfoEndpointReturnsRequestNot2xxTest() throws Exception {
Settings settings = Settings.builder()
.put("openid_connect_url", mockIdpServer.getDiscoverUri())
.put("userinfo_endpoint", mockIdpServer.getUserinfoUri())
.put("required_issuer", TestJwts.TEST_ISSUER)
.put("required_audience", TestJwts.TEST_AUDIENCE + ",another_audience")
.build();

HTTPOpenIdAuthenticator openIdAuthenticator = new HTTPOpenIdAuthenticator(settings, null);

AuthCredentials creds = openIdAuthenticator.extractCredentials(
new FakeRestRequest(ImmutableMap.of("Authorization", TestJwts.MC_COY_SIGNED_OCT_1), new HashMap<>()).asSecurityRequest(),
null
);

Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is(TestJwts.MCCOY_SUBJECT));
assertThat(creds.getAttributes().get("attr.jwt.aud"), is(List.of(TestJwts.TEST_AUDIENCE).toString()));
assertThat(creds.getBackendRoles().size(), is(0));
assertThat(creds.getAttributes().size(), is(4));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

class MockIpdServer implements Closeable {
final static String CTX_DISCOVER = "/discover";
final static String CTX_USERINFO = "/api/oauth/userinfo";
final static String CTX_KEYS = "/api/oauth/keys";

private final HttpServer httpServer;
Expand Down Expand Up @@ -119,6 +120,10 @@ public String getDiscoverUri() {
return uri + CTX_DISCOVER;
}

public String getUserinfoUri() {
return uri + CTX_USERINFO;
}

public String getJwksUri() {
return uri + CTX_KEYS;
}
Expand Down

0 comments on commit 5aeb90e

Please sign in to comment.