use of org.keycloak.services.CorsErrorResponseException 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.services.CorsErrorResponseException in project keycloak by keycloak.
the class AuthorizationTokenService method fireErrorEvent.
private static void fireErrorEvent(EventBuilder event, String error, Exception cause) {
if (cause instanceof CorsErrorResponseException) {
// cast the exception to populate the event with a more descriptive reason
CorsErrorResponseException originalCause = (CorsErrorResponseException) cause;
event.detail(Details.REASON, originalCause.getErrorDescription() == null ? "<unknown>" : originalCause.getErrorDescription()).error(error);
} else {
event.detail(Details.REASON, cause == null || cause.getMessage() == null ? "<unknown>" : cause.getMessage()).error(error);
}
logger.debug(event.getEvent().getType(), cause);
}
use of org.keycloak.services.CorsErrorResponseException in project keycloak by keycloak.
the class AuthorizationTokenService method resolveResourcePermission.
private void resolveResourcePermission(KeycloakAuthorizationRequest request, ResourceServer resourceServer, KeycloakIdentity identity, AuthorizationProvider authorization, StoreFactory storeFactory, Map<String, ResourcePermission> permissionsToEvaluate, ResourceStore resourceStore, AtomicInteger limit, Permission permission, Set<Scope> requestedScopesModel, String resourceId) {
Resource resource;
if (resourceId.indexOf('-') != -1) {
resource = resourceStore.findById(resourceId, resourceServer.getId());
} else {
resource = null;
}
if (resource != null) {
addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource);
} else if (resourceId.startsWith("resource-type:")) {
// only resource types, no resource instances. resource types are owned by the resource server
String resourceType = resourceId.substring("resource-type:".length());
resourceStore.findByType(resourceType, resourceServer.getId(), resourceServer.getId(), resource1 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource1));
} else if (resourceId.startsWith("resource-type-any:")) {
// any resource with a given type
String resourceType = resourceId.substring("resource-type-any:".length());
resourceStore.findByType(resourceType, null, resourceServer.getId(), resource12 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource12));
} else if (resourceId.startsWith("resource-type-instance:")) {
// only resource instances with a given type
String resourceType = resourceId.substring("resource-type-instance:".length());
resourceStore.findByTypeInstance(resourceType, resourceServer.getId(), resource13 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource13));
} else if (resourceId.startsWith("resource-type-owner:")) {
// only resources where the current identity is the owner
String resourceType = resourceId.substring("resource-type-owner:".length());
resourceStore.findByType(resourceType, identity.getId(), resourceServer.getId(), resource14 -> addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, resource14));
} else {
Resource ownerResource = resourceStore.findByName(resourceId, identity.getId(), resourceServer.getId());
if (ownerResource != null) {
permission.setResourceId(ownerResource.getId());
addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, ownerResource);
}
if (!identity.isResourceServer() || !identity.getId().equals(resourceServer.getId())) {
List<PermissionTicket> tickets = storeFactory.getPermissionTicketStore().findGranted(resourceId, identity.getId(), resourceServer.getId());
if (!tickets.isEmpty()) {
List<Scope> scopes = new ArrayList<>();
Resource grantedResource = null;
for (PermissionTicket permissionTicket : tickets) {
if (grantedResource == null) {
grantedResource = permissionTicket.getResource();
}
scopes.add(permissionTicket.getScope());
}
requestedScopesModel.retainAll(scopes);
ResourcePermission resourcePermission = addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, grantedResource);
// the permission is explicitly granted by the owner, mark this permission as granted so that we don't run the evaluation engine on it
resourcePermission.setGranted(true);
}
Resource serverResource = resourceStore.findByName(resourceId, resourceServer.getId());
if (serverResource != null) {
permission.setResourceId(serverResource.getId());
addPermission(request, resourceServer, authorization, permissionsToEvaluate, limit, requestedScopesModel, serverResource);
}
}
}
if (permissionsToEvaluate.isEmpty()) {
CorsErrorResponseException invalidResourceException = new CorsErrorResponseException(request.getCors(), "invalid_resource", "Resource with id [" + resourceId + "] does not exist.", Status.BAD_REQUEST);
fireErrorEvent(request.getEvent(), Errors.INVALID_REQUEST, invalidResourceException);
throw invalidResourceException;
}
}
use of org.keycloak.services.CorsErrorResponseException in project keycloak by keycloak.
the class AuthorizationTokenService method getResourceServer.
private ResourceServer getResourceServer(PermissionTicketToken ticket, KeycloakAuthorizationRequest request) {
AuthorizationProvider authorization = request.getAuthorization();
StoreFactory storeFactory = authorization.getStoreFactory();
ResourceServerStore resourceServerStore = storeFactory.getResourceServerStore();
String issuedFor = ticket.getIssuedFor();
if (issuedFor == null) {
CorsErrorResponseException missingIssuedForException = new CorsErrorResponseException(request.getCors(), OAuthErrorException.INVALID_REQUEST, "You must provide the issuedFor", Status.BAD_REQUEST);
fireErrorEvent(request.getEvent(), Errors.INVALID_REQUEST, missingIssuedForException);
throw missingIssuedForException;
}
ClientModel clientModel = request.getRealm().getClientByClientId(issuedFor);
if (clientModel == null) {
CorsErrorResponseException unknownServerIdException = new CorsErrorResponseException(request.getCors(), OAuthErrorException.INVALID_REQUEST, "Unknown resource server id: [" + issuedFor + "]", Status.BAD_REQUEST);
fireErrorEvent(request.getEvent(), Errors.INVALID_REQUEST, unknownServerIdException);
throw unknownServerIdException;
}
ResourceServer resourceServer = resourceServerStore.findByClient(clientModel);
if (resourceServer == null) {
CorsErrorResponseException unsupportedPermissionsException = new CorsErrorResponseException(request.getCors(), OAuthErrorException.INVALID_REQUEST, "Client does not support permissions", Status.BAD_REQUEST);
fireErrorEvent(request.getEvent(), Errors.INVALID_REQUEST, unsupportedPermissionsException);
throw unsupportedPermissionsException;
}
return resourceServer;
}
use of org.keycloak.services.CorsErrorResponseException in project keycloak by keycloak.
the class AuthorizationTokenService method createEvaluationContext.
private EvaluationContext createEvaluationContext(KeycloakAuthorizationRequest request) {
String claimTokenFormat = request.getClaimTokenFormat();
if (claimTokenFormat == null) {
claimTokenFormat = CLAIM_TOKEN_FORMAT_JWT;
}
BiFunction<KeycloakAuthorizationRequest, AuthorizationProvider, EvaluationContext> evaluationContextProvider = SUPPORTED_CLAIM_TOKEN_FORMATS.get(claimTokenFormat);
if (evaluationContextProvider == null) {
CorsErrorResponseException unsupportedClaimTokenFormatException = new CorsErrorResponseException(request.getCors(), OAuthErrorException.INVALID_REQUEST, "Claim token format [" + claimTokenFormat + "] not supported", Status.BAD_REQUEST);
fireErrorEvent(request.getEvent(), Errors.INVALID_REQUEST, unsupportedClaimTokenFormatException);
throw unsupportedClaimTokenFormatException;
}
return evaluationContextProvider.apply(request, request.getAuthorization());
}
Aggregations