use of org.keycloak.authorization.AuthorizationProvider 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.authorization.AuthorizationProvider in project keycloak by keycloak.
the class AccountFormService method shareResource.
@Path("resource/{resource_id}/share")
@POST
public Response shareResource(@PathParam("resource_id") String resourceId, @FormParam("user_id") String[] userIds, @FormParam("scope_id") String[] scopes) {
MultivaluedMap<String, String> formData = request.getDecodedFormParameters();
if (auth == null) {
return login("resource");
}
auth.require(AccountRoles.MANAGE_ACCOUNT);
csrfCheck(formData);
AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class);
PermissionTicketStore ticketStore = authorization.getStoreFactory().getPermissionTicketStore();
Resource resource = authorization.getStoreFactory().getResourceStore().findById(resourceId, null);
ResourceServer resourceServer = authorization.getStoreFactory().getResourceServerStore().findById(resource.getResourceServer());
if (resource == null) {
return ErrorResponse.error("Invalid resource", Response.Status.BAD_REQUEST);
}
if (userIds == null || userIds.length == 0) {
setReferrerOnPage();
return account.setError(Status.BAD_REQUEST, Messages.MISSING_PASSWORD).createResponse(AccountPages.PASSWORD);
}
for (String id : userIds) {
UserModel user = session.users().getUserById(realm, id);
if (user == null) {
user = session.users().getUserByUsername(realm, id);
}
if (user == null) {
user = session.users().getUserByEmail(realm, id);
}
if (user == null) {
setReferrerOnPage();
return account.setError(Status.BAD_REQUEST, Messages.INVALID_USER).createResponse(AccountPages.RESOURCE_DETAIL);
}
Map<PermissionTicket.FilterOption, String> filters = new EnumMap<>(PermissionTicket.FilterOption.class);
filters.put(PermissionTicket.FilterOption.RESOURCE_ID, resource.getId());
filters.put(PermissionTicket.FilterOption.OWNER, auth.getUser().getId());
filters.put(PermissionTicket.FilterOption.REQUESTER, user.getId());
List<PermissionTicket> tickets = ticketStore.find(filters, resource.getResourceServer(), -1, -1);
if (tickets.isEmpty()) {
if (scopes != null && scopes.length > 0) {
for (String scope : scopes) {
PermissionTicket ticket = ticketStore.create(resourceId, scope, user.getId(), resourceServer);
ticket.setGrantedTimestamp(System.currentTimeMillis());
}
} else {
if (resource.getScopes().isEmpty()) {
PermissionTicket ticket = ticketStore.create(resourceId, null, user.getId(), resourceServer);
ticket.setGrantedTimestamp(System.currentTimeMillis());
} else {
for (Scope scope : resource.getScopes()) {
PermissionTicket ticket = ticketStore.create(resourceId, scope.getId(), user.getId(), resourceServer);
ticket.setGrantedTimestamp(System.currentTimeMillis());
}
}
}
} else if (scopes != null && scopes.length > 0) {
List<String> grantScopes = new ArrayList<>(Arrays.asList(scopes));
for (PermissionTicket ticket : tickets) {
Scope scope = ticket.getScope();
if (scope != null) {
grantScopes.remove(scope.getId());
}
}
for (String grantScope : grantScopes) {
PermissionTicket ticket = ticketStore.create(resourceId, grantScope, user.getId(), resourceServer);
ticket.setGrantedTimestamp(System.currentTimeMillis());
}
}
}
return forwardToPage("resource", AccountPages.RESOURCE_DETAIL);
}
use of org.keycloak.authorization.AuthorizationProvider in project keycloak by keycloak.
the class PolicyEvaluationTest method testCheckUserClientRoles.
public static void testCheckUserClientRoles(KeycloakSession session) {
session.getContext().setRealm(session.realms().getRealmByName("authz-test"));
AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class);
ClientModel clientModel = session.clients().getClientByClientId(session.getContext().getRealm(), "resource-server-test");
StoreFactory storeFactory = authorization.getStoreFactory();
ResourceServer resourceServer = storeFactory.getResourceServerStore().findByClient(clientModel);
JSPolicyRepresentation policyRepresentation = new JSPolicyRepresentation();
policyRepresentation.setName("testCheckUserClientRoles");
StringBuilder builder = new StringBuilder();
builder.append("var realm = $evaluation.getRealm();");
builder.append("var roles = realm.getUserClientRoles('trinity', 'role-mapping-client');");
builder.append("if (roles.size() == 1 && roles.contains('client-role-a')) { $evaluation.grant(); }");
policyRepresentation.setCode(builder.toString());
Policy policy = storeFactory.getPolicyStore().create(policyRepresentation, resourceServer);
PolicyProvider provider = authorization.getProvider(policy.getType());
DefaultEvaluation evaluation = createEvaluation(session, authorization, resourceServer, policy);
provider.evaluate(evaluation);
Assert.assertEquals(Effect.PERMIT, evaluation.getEffect());
}
use of org.keycloak.authorization.AuthorizationProvider in project keycloak by keycloak.
the class PolicyEvaluationTest method testCheckDateAndTime.
public static void testCheckDateAndTime(KeycloakSession session) {
session.getContext().setRealm(session.realms().getRealmByName("authz-test"));
AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class);
ClientModel clientModel = session.clients().getClientByClientId(session.getContext().getRealm(), "resource-server-test");
StoreFactory storeFactory = authorization.getStoreFactory();
ResourceServer resourceServer = storeFactory.getResourceServerStore().findByClient(clientModel);
TimePolicyRepresentation policyRepresentation = new TimePolicyRepresentation();
policyRepresentation.setName("testCheckDateAndTime");
// set the notOnOrAfter for 1 hour from now
long notOnOrAfter = System.currentTimeMillis() + 3600000;
Date notOnOrAfterDate = new Date(notOnOrAfter);
policyRepresentation.setNotOnOrAfter(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(notOnOrAfterDate));
// evaluation should succeed with the default context as it uses the current time as the date to be compared.
Policy policy = storeFactory.getPolicyStore().create(policyRepresentation, resourceServer);
PolicyProvider provider = authorization.getProvider(policy.getType());
DefaultEvaluation evaluation = createEvaluation(session, authorization, resourceServer, policy);
provider.evaluate(evaluation);
Assert.assertEquals(Effect.PERMIT, evaluation.getEffect());
// lets now override the context to use a time that exceeds the time that was set in the policy.
long contextTime = System.currentTimeMillis() + 5400000;
Map<String, Collection<String>> attributes = new HashMap<>();
attributes.put("kc.time.date_time", Arrays.asList(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(contextTime))));
evaluation = createEvaluation(session, authorization, null, resourceServer, policy, attributes);
provider.evaluate(evaluation);
Assert.assertEquals(Effect.DENY, evaluation.getEffect());
}
use of org.keycloak.authorization.AuthorizationProvider in project keycloak by keycloak.
the class PolicyEvaluationTest method testCheckReadOnlyInstances.
public static void testCheckReadOnlyInstances(KeycloakSession session) {
session.getContext().setRealm(session.realms().getRealmByName("authz-test"));
AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class);
ClientModel clientModel = session.clients().getClientByClientId(session.getContext().getRealm(), "resource-server-test");
StoreFactory storeFactory = authorization.getStoreFactory();
ResourceServer resourceServer = storeFactory.getResourceServerStore().findByClient(clientModel);
JSPolicyRepresentation policyRepresentation = new JSPolicyRepresentation();
policyRepresentation.setName("testCheckReadOnlyInstances");
StringBuilder builder = new StringBuilder();
builder.append("$evaluation.getPermission().getResource().setName('test')");
policyRepresentation.setCode(builder.toString());
Policy policy = storeFactory.getPolicyStore().create(policyRepresentation, resourceServer);
Resource resource = storeFactory.getResourceStore().create("Resource A", resourceServer, resourceServer.getId());
Scope scope = storeFactory.getScopeStore().create("Scope A", resourceServer);
resource.updateScopes(new HashSet<>(Arrays.asList(scope)));
ResourcePermissionRepresentation permission = new ResourcePermissionRepresentation();
permission.setName("testCheckReadOnlyInstances permission");
permission.addPolicy(policy.getId());
permission.addResource(resource.getId());
storeFactory.getPolicyStore().create(permission, resourceServer);
session.getTransactionManager().commit();
PermissionEvaluator evaluator = authorization.evaluators().from(Arrays.asList(new ResourcePermission(resource, Arrays.asList(scope), resourceServer)), createEvaluationContext(session, Collections.emptyMap()));
try {
evaluator.evaluate(resourceServer, null);
Assert.fail("Instances should be marked as read-only");
} catch (Exception ignore) {
}
}
Aggregations