Do not return empty scope field in token introspection response

Closes #16526
This commit is contained in:
Moritz Becker 2023-10-09 09:05:26 +02:00 committed by Marek Posolda
parent 478ceb0b34
commit e9f08b6500
2 changed files with 38 additions and 0 deletions

View file

@ -61,6 +61,11 @@ public class AccessTokenIntrospectionProvider implements TokenIntrospectionProvi
tokenMetadata = JsonSerialization.createObjectNode(accessToken);
tokenMetadata.put("client_id", accessToken.getIssuedFor());
String scope = accessToken.getScope();
if (scope != null && scope.trim().isEmpty()) {
tokenMetadata.remove("scope");
}
if (!tokenMetadata.has("username")) {
if (accessToken.getPreferredUsername() != null) {
tokenMetadata.put("username", accessToken.getPreferredUsername());

View file

@ -101,6 +101,16 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest {
samlApp.setServiceAccountsEnabled(Boolean.TRUE);
samlApp.setProtocol("saml");
ClientRepresentation noScopeApp = KeycloakModelUtils.createClient(testRealm, "no-scope");
noScopeApp.setEnabled(true);
noScopeApp.setSecret("password");
noScopeApp.setRedirectUris(List.of(
"http://localhost:8180/auth/realms/master/app/auth/*",
"https://localhost:8543/auth/realms/master/app/auth/*"
));
noScopeApp.setOptionalClientScopes(List.of());
noScopeApp.setDefaultClientScopes(List.of());
UserRepresentation user = new UserRepresentation();
user.setUsername("no-permissions");
CredentialRepresentation credential = new CredentialRepresentation();
@ -322,7 +332,30 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest {
AbstractOIDCScopeTest.assertScopes("openid email profile", rep.getScope());
}
@Test
public void testIntrospectAccessTokenWithoutScope() throws Exception {
oauth.clientId("no-scope").openid(false).doLogin("test-user@localhost", "password");
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
RealmRepresentation testRealm = adminClient.realm("test").toRepresentation();
List<ClientScopeRepresentation> preExistingClientScopes = testRealm.getClientScopes();
testRealm.setClientScopes(List.of());
adminClient.realm("test").update(testRealm);
try {
EventRepresentation loginEvent = events.expectLogin().client("no-scope").assertEvent();
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("no-scope", "password", accessTokenResponse.getAccessToken());
TokenMetadataRepresentation rep = JsonSerialization.readValue(tokenResponse, TokenMetadataRepresentation.class);
assertTrue(rep.isActive());
assertEquals("test-user@localhost", rep.getUserName());
assertEquals("no-scope", rep.getClientId());
assertEquals(loginEvent.getUserId(), rep.getSubject());
assertNull(rep.getScope());
} finally {
testRealm.setClientScopes(preExistingClientScopes);
adminClient.realm("test").update(testRealm);
}
}
@Test
public void testIntrospectAccessTokenES256() throws Exception {