use of org.keycloak.representations.idm.authorization.Permission in project keycloak by keycloak.
the class PolicyEnforcerTest method testResolvingClaimsOnce.
@Test
public void testResolvingClaimsOnce() {
KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-bearer-only-with-cip.json"));
PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer();
oauth.realm(REALM_NAME);
oauth.clientId("public-client-test");
oauth.doLogin("marta", "password");
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
OAuthClient.AccessTokenResponse response = oauth.doAccessTokenRequest(code, null);
String token = response.getAccessToken();
OIDCHttpFacade httpFacade = createHttpFacade("/api/resourcea", token, new Function<String, String>() {
AtomicBoolean resolved = new AtomicBoolean();
@Override
public String apply(String s) {
Assert.assertTrue(resolved.compareAndSet(false, true));
return "value-" + s;
}
});
AuthorizationContext context = policyEnforcer.enforce(httpFacade);
Permission permission = context.getPermissions().get(0);
Map<String, Set<String>> claims = permission.getClaims();
assertTrue(context.isGranted());
assertEquals("value-claim-a", claims.get("claim-a").iterator().next());
assertEquals("claim-b", claims.get("claim-b").iterator().next());
}
use of org.keycloak.representations.idm.authorization.Permission in project keycloak by keycloak.
the class PolicyEnforcerClaimsTest method testEnforceUMAAccessWithClaimsUsingBearerToken.
@Test
public void testEnforceUMAAccessWithClaimsUsingBearerToken() {
initAuthorizationSettings(getClientResource("resource-server-uma-test"));
KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(getAdapterConfiguration("enforcer-uma-claims-test.json"));
PolicyEnforcer policyEnforcer = deployment.getPolicyEnforcer();
HashMap<String, List<String>> headers = new HashMap<>();
HashMap<String, List<String>> parameters = new HashMap<>();
parameters.put("withdrawal.amount", Arrays.asList("50"));
AuthzClient authzClient = getAuthzClient("enforcer-uma-claims-test.json");
String token = authzClient.obtainAccessToken("marta", "password").getToken();
headers.put("Authorization", Arrays.asList("Bearer " + token));
AuthorizationContext context = policyEnforcer.enforce(createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters));
assertFalse(context.isGranted());
AuthorizationRequest request = new AuthorizationRequest();
request.setTicket(extractTicket(headers));
AuthorizationResponse response = authzClient.authorization("marta", "password").authorize(request);
token = response.getToken();
assertNotNull(token);
context = policyEnforcer.enforce(createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters));
assertTrue(context.isGranted());
parameters.put("withdrawal.amount", Arrays.asList("200"));
context = policyEnforcer.enforce(createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters));
assertFalse(context.isGranted());
parameters.put("withdrawal.amount", Arrays.asList("50"));
context = policyEnforcer.enforce(createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters));
assertTrue(context.isGranted());
parameters.put("withdrawal.amount", Arrays.asList("10"));
context = policyEnforcer.enforce(createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters));
request = new AuthorizationRequest();
request.setTicket(extractTicket(headers));
response = authzClient.authorization("marta", "password").authorize(request);
token = response.getToken();
context = policyEnforcer.enforce(createHttpFacade("/api/bank/account/1/withdrawal", "POST", token, headers, parameters));
assertTrue(context.isGranted());
request = new AuthorizationRequest();
request.setTicket(extractTicket(headers));
response = authzClient.authorization("marta", "password").authorize(request);
token = response.getToken();
context = policyEnforcer.enforce(createHttpFacade("/api/bank/account/1/withdrawal", "GET", token, headers, parameters));
assertTrue(context.isGranted());
assertEquals(1, context.getPermissions().size());
Permission permission = context.getPermissions().get(0);
assertEquals(parameters.get("withdrawal.amount").get(0), permission.getClaims().get("withdrawal.amount").iterator().next());
}
use of org.keycloak.representations.idm.authorization.Permission in project keycloak by keycloak.
the class AuthorizationTokenService method authorize.
public Response authorize(KeycloakAuthorizationRequest request) {
EventBuilder event = request.getEvent();
// it is not secure to allow public clients to push arbitrary claims because message can be tampered
if (isPublicClientRequestingEntitlementWithClaims(request)) {
CorsErrorResponseException forbiddenClientException = new CorsErrorResponseException(request.getCors(), OAuthErrorException.INVALID_GRANT, "Public clients are not allowed to send claims", Status.FORBIDDEN);
fireErrorEvent(event, Errors.INVALID_REQUEST, forbiddenClientException);
throw forbiddenClientException;
}
try {
PermissionTicketToken ticket = getPermissionTicket(request);
request.setClaims(ticket.getClaims());
EvaluationContext evaluationContext = createEvaluationContext(request);
KeycloakIdentity identity = KeycloakIdentity.class.cast(evaluationContext.getIdentity());
if (identity != null) {
event.user(identity.getId());
}
ResourceServer resourceServer = getResourceServer(ticket, request);
Collection<Permission> permissions;
if (request.getTicket() != null) {
permissions = evaluateUserManagedPermissions(request, ticket, resourceServer, evaluationContext);
} else if (ticket.getPermissions().isEmpty() && request.getRpt() == null) {
permissions = evaluateAllPermissions(request, resourceServer, evaluationContext);
} else {
permissions = evaluatePermissions(request, ticket, resourceServer, evaluationContext, identity);
}
if (isGranted(ticket, request, permissions)) {
AuthorizationProvider authorization = request.getAuthorization();
ClientModel targetClient = authorization.getRealm().getClientById(resourceServer.getId());
Metadata metadata = request.getMetadata();
String responseMode = metadata != null ? metadata.getResponseMode() : null;
if (responseMode != null) {
if (RESPONSE_MODE_DECISION.equals(metadata.getResponseMode())) {
Map<String, Object> responseClaims = new HashMap<>();
responseClaims.put(RESPONSE_MODE_DECISION_RESULT, true);
return createSuccessfulResponse(responseClaims, request);
} else if (RESPONSE_MODE_PERMISSIONS.equals(metadata.getResponseMode())) {
return createSuccessfulResponse(permissions, request);
} else {
CorsErrorResponseException invalidResponseModeException = new CorsErrorResponseException(request.getCors(), OAuthErrorException.INVALID_REQUEST, "Invalid response_mode", Status.BAD_REQUEST);
fireErrorEvent(event, Errors.INVALID_REQUEST, invalidResponseModeException);
throw invalidResponseModeException;
}
} else {
return createSuccessfulResponse(createAuthorizationResponse(identity, permissions, request, targetClient), request);
}
}
if (request.isSubmitRequest()) {
CorsErrorResponseException submittedRequestException = new CorsErrorResponseException(request.getCors(), OAuthErrorException.ACCESS_DENIED, "request_submitted", Status.FORBIDDEN);
fireErrorEvent(event, Errors.ACCESS_DENIED, submittedRequestException);
throw submittedRequestException;
} else {
CorsErrorResponseException notAuthorizedException = new CorsErrorResponseException(request.getCors(), OAuthErrorException.ACCESS_DENIED, "not_authorized", Status.FORBIDDEN);
fireErrorEvent(event, Errors.ACCESS_DENIED, notAuthorizedException);
throw notAuthorizedException;
}
} catch (ErrorResponseException | CorsErrorResponseException cause) {
if (logger.isDebugEnabled()) {
logger.debug("Error while evaluating permissions", cause);
}
throw cause;
} catch (Exception cause) {
logger.error("Unexpected error while evaluating permissions", cause);
throw new CorsErrorResponseException(request.getCors(), OAuthErrorException.SERVER_ERROR, "Unexpected error while evaluating permissions", Status.INTERNAL_SERVER_ERROR);
}
}
use of org.keycloak.representations.idm.authorization.Permission in project keycloak by keycloak.
the class AuthorizationTokenService method resolvePreviousGrantedPermissions.
private void resolvePreviousGrantedPermissions(PermissionTicketToken ticket, KeycloakAuthorizationRequest request, ResourceServer resourceServer, Map<String, ResourcePermission> permissionsToEvaluate, ResourceStore resourceStore, ScopeStore scopeStore, AtomicInteger limit) {
AccessToken rpt = request.getRpt();
if (rpt != null && rpt.isActive()) {
Authorization authorizationData = rpt.getAuthorization();
if (authorizationData != null) {
Collection<Permission> permissions = authorizationData.getPermissions();
if (permissions != null) {
for (Permission grantedPermission : permissions) {
if (limit != null && limit.get() <= 0) {
break;
}
Resource resource = resourceStore.findById(grantedPermission.getResourceId(), ticket.getIssuedFor());
if (resource != null) {
ResourcePermission permission = permissionsToEvaluate.get(resource.getId());
if (permission == null) {
permission = new ResourcePermission(resource, new ArrayList<>(), resourceServer, grantedPermission.getClaims());
permissionsToEvaluate.put(resource.getId(), permission);
if (limit != null) {
limit.decrementAndGet();
}
} else {
if (grantedPermission.getClaims() != null) {
for (Entry<String, Set<String>> entry : grantedPermission.getClaims().entrySet()) {
Set<String> claims = permission.getClaims().get(entry.getKey());
if (claims != null) {
claims.addAll(entry.getValue());
}
}
}
}
for (String scopeName : grantedPermission.getScopes()) {
Scope scope = scopeStore.findByName(scopeName, resourceServer.getId());
if (scope != null) {
if (!permission.getScopes().contains(scope)) {
permission.getScopes().add(scope);
}
}
}
}
}
}
}
}
}
use of org.keycloak.representations.idm.authorization.Permission in project keycloak by keycloak.
the class AbstractPermissionService method createPermissionTicket.
private String createPermissionTicket(List<PermissionRequest> request) {
List<Permission> permissions = verifyRequestedResource(request);
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) {
Map<String, List<String>> requestClaims = permissionRequest.getClaims();
if (requestClaims != null) {
claims.putAll(requestClaims);
}
}
if (!claims.isEmpty()) {
token.setClaims(claims);
}
return this.authorization.getKeycloakSession().tokens().encode(token);
}
Aggregations