use of org.keycloak.representations.idm.authorization.PermissionTicketToken in project keycloak by keycloak.
the class HttpMethodAuthenticator method uma.
public HttpMethod<R> uma(AuthorizationRequest request) {
String ticket = request.getTicket();
PermissionTicketToken permissions = request.getPermissions();
if (ticket == null && permissions == null) {
throw new IllegalArgumentException("You must either provide a permission ticket or the permissions you want to request.");
}
uma();
method.param("ticket", ticket);
method.param("claim_token", request.getClaimToken());
method.param("claim_token_format", request.getClaimTokenFormat());
method.param("pct", request.getPct());
method.param("rpt", request.getRptToken());
method.param("scope", request.getScope());
method.param("audience", request.getAudience());
method.param("subject_token", request.getSubjectToken());
if (permissions != null) {
for (Permission permission : permissions.getPermissions()) {
String resourceId = permission.getResourceId();
Set<String> scopes = permission.getScopes();
StringBuilder value = new StringBuilder();
if (resourceId != null) {
value.append(resourceId);
}
if (scopes != null && !scopes.isEmpty()) {
value.append("#");
for (String scope : scopes) {
if (!value.toString().endsWith("#")) {
value.append(",");
}
value.append(scope);
}
}
method.params("permission", value.toString());
}
}
Metadata metadata = request.getMetadata();
if (metadata != null) {
if (metadata.getIncludeResourceName() != null) {
method.param("response_include_resource_name", metadata.getIncludeResourceName().toString());
}
if (metadata.getLimit() != null) {
method.param("response_permissions_limit", metadata.getLimit().toString());
}
}
return method;
}
use of org.keycloak.representations.idm.authorization.PermissionTicketToken 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.PermissionTicketToken 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);
}
use of org.keycloak.representations.idm.authorization.PermissionTicketToken in project keycloak by keycloak.
the class AuthorizationTokenService method getPermissionTicket.
private PermissionTicketToken getPermissionTicket(KeycloakAuthorizationRequest request) {
// if there is a ticket is because it is a UMA flow and the ticket was sent by the client after obtaining it from the target resource server
if (request.getTicket() != null) {
return verifyPermissionTicket(request);
}
// if there is no ticket, we use the permissions the client is asking for.
// This is a Keycloak extension to UMA flow where clients are capable of obtaining a RPT without a ticket
PermissionTicketToken permissions = request.getPermissions();
// 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;
}
use of org.keycloak.representations.idm.authorization.PermissionTicketToken in project keycloak by keycloak.
the class AuthorizationTokenService method verifyPermissionTicket.
private PermissionTicketToken verifyPermissionTicket(KeycloakAuthorizationRequest request) {
String ticketString = request.getTicket();
PermissionTicketToken ticket = request.getKeycloakSession().tokens().decode(ticketString, PermissionTicketToken.class);
if (ticket == null) {
CorsErrorResponseException ticketVerificationException = new CorsErrorResponseException(request.getCors(), "invalid_ticket", "Ticket verification failed", Status.FORBIDDEN);
fireErrorEvent(request.getEvent(), Errors.INVALID_PERMISSION_TICKET, ticketVerificationException);
throw ticketVerificationException;
}
if (!ticket.isActive()) {
CorsErrorResponseException invalidTicketException = new CorsErrorResponseException(request.getCors(), "invalid_ticket", "Invalid permission ticket.", Status.FORBIDDEN);
fireErrorEvent(request.getEvent(), Errors.INVALID_PERMISSION_TICKET, invalidTicketException);
throw invalidTicketException;
}
return ticket;
}
Aggregations