KEYCLOAK-8641 Remove aud from the authorization tickets

This commit is contained in:
mposolda 2018-10-23 13:53:19 +02:00 committed by Marek Posolda
parent 9652748ba9
commit cfeb56e18a
4 changed files with 19 additions and 10 deletions

View file

@ -252,7 +252,6 @@ public class PolicyEvaluationService {
accessToken.subject(representation.getUserId());
accessToken.issuedFor(representation.getClientId());
accessToken.audience(representation.getClientId());
accessToken.issuer(Urls.realmIssuer(keycloakSession.getContext().getUri().getBaseUri(), realm.getName()));
accessToken.setRealmAccess(new AccessToken.Access());

View file

@ -331,8 +331,8 @@ public class AuthorizationTokenService {
// This is a Keycloak extension to UMA flow where clients are capable of obtaining a RPT without a ticket
PermissionTicketToken permissions = request.getPermissions();
// an audience must be set by the client when doing this method of obtaining RPT, that is how we know the target resource server
permissions.audience(request.getAudience());
// an issuedFor must be set by the client when doing this method of obtaining RPT, that is how we know the target resource server
permissions.issuedFor(request.getAudience());
return permissions;
}
@ -341,13 +341,13 @@ public class AuthorizationTokenService {
AuthorizationProvider authorization = request.getAuthorization();
StoreFactory storeFactory = authorization.getStoreFactory();
ResourceServerStore resourceServerStore = storeFactory.getResourceServerStore();
String[] audience = ticket.getAudience();
String issuedFor = ticket.getIssuedFor();
if (audience == null || audience.length == 0) {
throw new CorsErrorResponseException(request.getCors(), OAuthErrorException.INVALID_REQUEST, "You must provide the audience", Status.BAD_REQUEST);
if (issuedFor == null) {
throw new CorsErrorResponseException(request.getCors(), OAuthErrorException.INVALID_REQUEST, "You must provide the issuedFor", Status.BAD_REQUEST);
}
ClientModel clientModel = request.getRealm().getClientByClientId(audience[0]);
ClientModel clientModel = request.getRealm().getClientByClientId(issuedFor);
if (clientModel == null) {
throw new CorsErrorResponseException(request.getCors(), OAuthErrorException.INVALID_REQUEST, "Unknown resource server id.", Status.BAD_REQUEST);
@ -514,7 +514,7 @@ public class AuthorizationTokenService {
break;
}
Resource resource = resourceStore.findById(grantedPermission.getResourceId(), ticket.getAudience()[0]);
Resource resource = resourceStore.findById(grantedPermission.getResourceId(), ticket.getIssuedFor());
if (resource != null) {
ResourcePermission permission = permissionsToEvaluate.get(resource.getId());

View file

@ -29,6 +29,7 @@ import org.keycloak.representations.idm.authorization.PermissionRequest;
import org.keycloak.representations.idm.authorization.PermissionResponse;
import org.keycloak.representations.idm.authorization.PermissionTicketToken;
import org.keycloak.services.ErrorResponseException;
import org.keycloak.services.Urls;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
@ -148,8 +149,8 @@ public class AbstractPermissionService {
private String createPermissionTicket(List<PermissionRequest> request) {
List<Permission> permissions = verifyRequestedResource(request);
ClientModel targetClient = authorization.getRealm().getClientById(resourceServer.getId());
PermissionTicketToken token = new PermissionTicketToken(permissions, targetClient.getClientId(), this.identity.getAccessToken());
String audience = Urls.realmIssuer(this.authorization.getKeycloakSession().getContext().getUri().getBaseUri(), this.authorization.getRealm().getName());
PermissionTicketToken token = new PermissionTicketToken(permissions, audience, this.identity.getAccessToken());
Map<String, List<String>> claims = new HashMap<>();
for (PermissionRequest permissionRequest : request) {

View file

@ -32,7 +32,9 @@ import org.keycloak.admin.client.resource.ClientsResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.authorization.client.AuthzClient;
import org.keycloak.authorization.client.Configuration;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.JsonWebToken;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.authorization.AuthorizationRequest;
import org.keycloak.representations.idm.authorization.AuthorizationResponse;
@ -40,6 +42,7 @@ import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
import org.keycloak.representations.idm.authorization.PermissionRequest;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.RealmBuilder;
@ -184,6 +187,12 @@ public class AuthorizationAPITest extends AbstractAuthzTest {
String accessToken = new OAuthClient().realm("authz-test").clientId(clientId).doGrantAccessTokenRequest("secret", "marta", "password").getAccessToken();
String ticket = authzClient.protection().permission().create(request).getTicket();
// Ticket is opaque to client or resourceServer. The audience should be just an authorization server itself
JsonWebToken ticketDecoded = JsonSerialization.readValue(new JWSInput(ticket).getContent(), JsonWebToken.class);
Assert.assertFalse(ticketDecoded.hasAudience(clientId));
Assert.assertFalse(ticketDecoded.hasAudience(resourceServerClientId));
AuthorizationResponse response = authzClient.authorization(accessToken).authorize(new AuthorizationRequest(ticket));
assertNotNull(response.getToken());