diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java index 07a6da56d5..5b70d9b196 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/TokenEndpoint.java @@ -595,10 +595,36 @@ public class TokenEndpoint { boolean allowed = false; UserModel serviceAccount = session.users().getServiceAccount(client); if (serviceAccount != null) { - RoleModel exchangeable = targetClient.getRole(OAuth2Constants.TOKEN_EXCHANGER); - RoleModel realmExchangeable = AdminPermissions.management(session, realm).getRealmManagementClient().getRole(OAuth2Constants.TOKEN_EXCHANGER); - allowed = (exchangeable != null && serviceAccount.hasRole(exchangeable)) || (realmExchangeable != null && serviceAccount.hasRole(realmExchangeable)); + if (authResult.getToken().getAudience() == null) { + logger.debug("Client doesn't have service account"); + } + boolean tokenAllowed = false; + for (String aud : authResult.getToken().getAudience()) { + ClientModel audClient = realm.getClientByClientId(aud); + if (audClient == null) continue; + if (audClient.equals(client)) { + tokenAllowed = true; + break; + } + RoleModel audExchanger = audClient.getRole(OAuth2Constants.TOKEN_EXCHANGER); + if (audExchanger != null && serviceAccount.hasRole(audExchanger)) { + tokenAllowed = true; + break; + } + } + if (!tokenAllowed) { + logger.debug("Client does not have exchange rights for audience of token"); + } else { + RoleModel targetExchangable = targetClient.getRole(OAuth2Constants.TOKEN_EXCHANGER); + RoleModel realmExchangeable = AdminPermissions.management(session, realm).getRealmManagementClient().getRole(OAuth2Constants.TOKEN_EXCHANGER); + allowed = (targetExchangable != null && serviceAccount.hasRole(targetExchangable)) || (realmExchangeable != null && serviceAccount.hasRole(realmExchangeable)); + if (!allowed) { + logger.debug("Client does not have exchange rights for target audience"); + } + } + } else { + logger.debug("Client doesn't have service account"); } if (!allowed) { diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java index a3983a4ac6..7961163231 100755 --- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java +++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java @@ -221,18 +221,6 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal } - // only allow origins from client. Not sure we need this as I don't believe cookies can be - // sent if CORS preflight requests can't execute. - String origin = headers.getRequestHeaders().getFirst("Origin"); - if (origin != null) { - String redirectOrigin = UriUtils.getOrigin(redirectUri); - if (!redirectOrigin.equals(origin)) { - event.error(Errors.ILLEGAL_ORIGIN); - throw new ErrorPageException(session, Messages.INVALID_REQUEST); - - } - } - AuthenticationManager.AuthResult cookieResult = AuthenticationManager.authenticateIdentityCookie(session, realmModel, true); String errorParam = "link_error"; if (cookieResult == null) {