{"id":20471539,"url":"https://github.com/backbase/sample-service-with-access-control","last_synced_at":"2025-08-10T07:13:09.602Z","repository":{"id":53277199,"uuid":"292831925","full_name":"Backbase/sample-service-with-access-control","owner":"Backbase","description":null,"archived":false,"fork":false,"pushed_at":"2021-03-31T22:15:48.000Z","size":9,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-07-29T17:06:04.687Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Backbase.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-09-04T11:34:19.000Z","updated_at":"2021-04-06T08:24:19.000Z","dependencies_parsed_at":"2022-08-27T07:42:11.587Z","dependency_job_id":null,"html_url":"https://github.com/Backbase/sample-service-with-access-control","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Backbase/sample-service-with-access-control","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Backbase%2Fsample-service-with-access-control","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Backbase%2Fsample-service-with-access-control/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Backbase%2Fsample-service-with-access-control/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Backbase%2Fsample-service-with-access-control/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Backbase","download_url":"https://codeload.github.com/Backbase/sample-service-with-access-control/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Backbase%2Fsample-service-with-access-control/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269689772,"owners_count":24459711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T14:16:26.870Z","updated_at":"2025-08-10T07:13:09.583Z","avatar_url":"https://github.com/Backbase.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Implement Access control in a custom capability\n## Implement Access Control.\n\n[Example: Implement Access control in a custom capability from Community](https://community.backbase.com/documentation/DBS/latest/entitlements_integrate_into_a_capability)\n\n## Description\nThis example shows you how to integrate Access Control into another service.\nYou use Access Control to easily allow specific users to perform clearly defined tasks on a limited group of arrangements.\nPermissions are evaluated with an OR operator; the user must be assigned at least one permission to complete the function\n they require. When the user has permissions to perform the specified function, the request proceeds to the requested \n handler method. Otherwise, HTTP 403 (Forbidden) is returned.\n \n## How to use\n### 1. Create a new project\n\nCreate a new project based on service-sdk-starter-core:\n\n      \u003cparent\u003e\n        \u003cartifactId\u003eservice-sdk-starter-core\u003c/artifactId\u003e\n        \u003cgroupId\u003ecom.backbase.buildingblocks\u003c/groupId\u003e\n        \u003cversion\u003eLATEST\u003c/version\u003e\n        \u003crelativePath/\u003e\n      \u003c/parent\u003e\n\nTo use access control in your custom service add the following dependency inside your pom.xml:\n\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.backbase.dbs.accesscontrol\u003c/groupId\u003e\n        \u003cartifactId\u003eauth-security-dbs-accesscontrol\u003c/artifactId\u003e\n        \u003cversion\u003e[specify version]\u003c/version\u003e\n    \u003c/dependency\u003e\n    \n### 2. Integrate Access Control into your code\n\n#### Use the library:\n\nTo provide a convenient method for access control using the Entitlements engine, auth-security-dbs-accesscontrol uses the Spring Security `@PreAuthorize` annotation in combination with a custom security expression.\n\nTo use the annotation to check permissions, supply a function name, resource name and a privilege:\n \n    @PreAuthorize(\"checkPermission('[your_resource_name]', '[your_function_name]', {'[privilege]'})\")\n\nAdd the @PreAuthorize annotation on your REST controller handler methods. For example:\n\n\n    @PreAuthorize(\"checkPermission('Payments', 'Domestic Payments', {'create'})\")\n    @RequestMapping(method = {RequestMethod.POST}, value = {\"\"})\n    @ResponseStatus(HttpStatus.CREATED)\n    public void createPayment(@RequestBody @Valid CreatePaymentPostRequestBody payment){\n    //TODO Implement method\n    }\n    \nIn this example, a check is made that the user making the request (as identified by the JWT token) has been assigned a function group with a 'create' privilege for a 'Payments' resource and 'Domestic Payments' function.\n\nIf the user is privileged to perform the specified function on a resource, the request will proceed with the request handler method. Otherwise, an HTTP 403 Forbidden status code is returned.\n\n### 3. Manually integrate Access Control into your code\nTo manually verify the configuration, use the service GET methods of the following endpoints:\n\n#### a. Configure DBS auth-security access control:\nMake a GET request to: /access-control/service-api/v2/accessgroups/users/permissions?userId=\u003cInternal User ID\u003e\u0026serviceAgreementId=\u003cService agreement ID\u003e\u0026functionName=\u003cFunction Name\u003e\u0026resourceName=\u003cResource Name\u003e\u0026privileges=\u003cPrivilege\u003e\n\n    presentationAccessgroupUsersClient\n    .getUserPermissionCheck(permissionsQueryParameters);\n    \n#### b.Check the list of all privileges:\nRetrieve all privileges for a user under single service agreement for legal entity Backbase. Make a GET request to: /access-control/service-api/v2/accessgroups/users/privileges?userId=\u0026\u003cInternal User ID\u003e\u0026serviceAgreementId=\u003cService agreement ID\u003e\u0026functionName=\u003cFunction Name\u003e\u0026resourceName=\u003cResource\u003e\n\n    ResponseEntity\u003c? extends List\u003ccom.backbase.presentation.accessgroup.rest.spec.v2.accessgroups.users.PrivilegesGetResponseBody\u003e\u003e privileges = presentationAccessgroupUsersClient.getPrivileges(permissionsQueryParameters);\n\n\n#### c.Get the list of arrangements with privileges:\nRetrieve a list of arrangements for a user called “Jonathan”. Make a GET request to: /access-control/service-api/v2/accessgroups/users/privileges/arrangements?userId=\u003cInternal User ID\u003e\u0026serviceAgreementId=\u003cService agreement ID\u003e\u0026functionName=\u003cFunction Name\u003e\u0026resourceName=\u003cResource Name\u003e\u0026privilegeName=\u003cPrivilege\u003e\n\n    public ResponseEntity\u003c? extends List\u003ccom.backbase.presentation.accessgroup.rest.spec.v2.accessgroups.users.ArrangementPrivilegesGetResponseBody\u003e\u003e arrangementPrivileges = presentationAccessgroupUsersClient.getArrangementPrivileges(permissionsQueryParameters);\n\n#### d.Check the permission for an arrangement:\nCheck if a user in the service agreement has some permission over a specific arrangement. Make a GET request to: /access-control/service-api/v2/accessgroups/users/user-privileges/arrangements/\u003carrangement-internal_id\u003e?function=\u003cFunction Name\u003e\u0026resource=\u003cResource Name\u003e\u0026privilege=\u003cPrivilege\u003e\n\n    presentationAccessgroupUsersClient.getArrangementPermissionCheck(arrangementId, permissionsQueryParameters);\n    \n#### e.Check if the user has permissions to access users or arrangements that belong to the list of legal entities:\nYou should use the method `userHasNoAccessToEntitlementsResource` in the component `AccessControlValidator`. For example:\n    \n    Boolean hasNoAccess = accessControlValidator.userHasNoAccessToEntitlementResource\n    (legalEntities, AccessResourceType.ACCOUNT);\n\n    Boolean hasNoAccess = accessControlValidator.userHasNoAccessToEntitlementResource\n    (legalEntities, AccessResourceType.USER);\n    \n    Boolean hasNoAccess = accessControlValidator.userHasNoAccessToEntitlementResource\n    (legalEntities, AccessResourceType.USER_OR_ACCOUNT);\n    \n#### f.Check if the user has permissions to access users or arrangements that belong to service agreement:\nYou should use the method `userHasNoAccessToServiceAgreement` in the component `AccessControlValidator`. For example:\n\n    Boolean hasNoAccess = accessControlValidator.userHasNoAccessToServiceAgreement\n    (serviceAgreementId, AccessResourceType.ACCOUNT);\n\n    Boolean hasNoAccess = accessControlValidator.userHasNoAccessToServiceAgreement\n    (serviceAgreementId, AccessResourceType.USER);\n\n    Boolean hasNoAccess = accessControlValidator.userHasNoAccessToServiceAgreement\n    (serviceAgreementId, AccessResourceType.USER_OR_ACCOUNT);\n\n\n### 4. Create a business function\nDepending on your database type, to add a new business function for your service in the Access Control database, update and run one of the following example scripts for your database:\n\nMySQL:\n\n    INSERT INTO `business_function`\n    (\n      `id`,\n      `function_code`,\n      `function_name`,\n      `resource_code`,\n      `resource_name`\n    )\n    VALUES\n      ('1014', 'manage.shadow.limits', 'Manage Shadow Limits', 'limits', 'Limits');\n     \n    INSERT INTO `applicable_function_privilege`\n    (\n      `id`,\n      `business_function_name`,\n      `function_resource_name`,\n      `privilege_name`,\n      `supports_limit`,\n      `business_function_id`,\n      `privilege_id`\n    )\n    VALUES\n      ('33', 'Manage Shadow Limits', 'Limits', 'view', '0', '1014', '2'),\n      ('34', 'Manage Shadow Limits', 'Limits', 'create', '0', '1014', '3'),\n      ('35', 'Manage Shadow Limits', 'Limits', 'edit', '0', '1014', '4'),\n      ('36', 'Manage Shadow Limits', 'Limits', 'delete', '0', '1014', '5');\n     \n    INSERT INTO `assignable_permission_set_item`(\n        assignable_permission_set_id,\n        function_privilege_id\n    )\n    VALUES\n        (1, '33'),\n        (1, '34'),\n        (1, '35'),\n        (1, '36');\n\n\nOracle:\n\n    INSERT INTO BUSINESS_FUNCTION\n    (ID, FUNCTION_CODE, FUNCTION_NAME, RESOURCE_CODE, RESOURCE_NAME)\n    VALUES\n      ('1014', 'manage.shadow.limits', 'Manage Shadow Limits', 'limits', 'Limits');\n     \n    INSERT INTO APPLICABLE_FUNCTION_PRIVILEGE\n    (ID, BUSINESS_FUNCTION_NAME, FUNCTION_RESOURCE_NAME, PRIVILEGE_NAME, SUPPORTS_LIMIT, BUSINESS_FUNCTION_ID, PRIVILEGE_ID)\n    VALUES\n      ('33', 'Manage Shadow Limits', 'Limits', 'view', '0', '1014', '2');\n     \n    INSERT INTO APPLICABLE_FUNCTION_PRIVILEGE\n    (ID, BUSINESS_FUNCTION_NAME, FUNCTION_RESOURCE_NAME, PRIVILEGE_NAME, SUPPORTS_LIMIT, BUSINESS_FUNCTION_ID, PRIVILEGE_ID)\n    VALUES\n      ('34', 'Manage Shadow Limits', 'Limits', 'create', '0', '1014', '3');\n     \n    INSERT INTO APPLICABLE_FUNCTION_PRIVILEGE\n    (ID, BUSINESS_FUNCTION_NAME, FUNCTION_RESOURCE_NAME, PRIVILEGE_NAME, SUPPORTS_LIMIT, BUSINESS_FUNCTION_ID, PRIVILEGE_ID)\n    VALUES\n      ('35', 'Manage Shadow Limits', 'Limits', 'edit', '0', '1014', '4');\n     \n    INSERT INTO APPLICABLE_FUNCTION_PRIVILEGE\n    (ID, BUSINESS_FUNCTION_NAME, FUNCTION_RESOURCE_NAME, PRIVILEGE_NAME, SUPPORTS_LIMIT, BUSINESS_FUNCTION_ID, PRIVILEGE_ID)\n    VALUES\n      ('36', 'Manage Shadow Limits', 'Limits', 'delete', '0', '1014', '5');\n     \n    INSERT INTO ASSIGNABLE_PERMISSION_SET_ITEM\n    (ASSIGNABLE_PERMISSION_SET_ID, FUNCTION_PRIVILEGE_ID)\n    VALUES\n        (1, '33');\n     \n    INSERT INTO ASSIGNABLE_PERMISSION_SET_ITEM\n    (ASSIGNABLE_PERMISSION_SET_ID, FUNCTION_PRIVILEGE_ID)\n    VALUES\n        (1, '34');\n     \n    INSERT INTO ASSIGNABLE_PERMISSION_SET_ITEM\n    (ASSIGNABLE_PERMISSION_SET_ID, FUNCTION_PRIVILEGE_ID)\n    VALUES\n        (1, '35');\n     \n    INSERT INTO ASSIGNABLE_PERMISSION_SET_ITEM\n    (ASSIGNABLE_PERMISSION_SET_ID, FUNCTION_PRIVILEGE_ID)\n    VALUES\n        (1, '36');\n     \n    commit;\n\nMicrosoft SqlServer:\n\n    insert into [business_function]\n    ( [id], [function_code], [function_name], [resource_code], [resource_name] )\n    values\n      ('1014', 'manage.shadow.limits', 'Manage Shadow Limits', 'limits', 'Limits');\n    go\n     \n    insert into [applicable_function_privilege]\n    (\n      [id],\n      [business_function_name],\n      [function_resource_name],\n      [privilege_name],\n      [supports_limit],\n      [business_function_id],\n      [privilege_id]\n    )\n    values\n      ('33', 'Manage Shadow Limits', 'Limits', 'view', '0', '1014', '2'),\n      ('34', 'Manage Shadow Limits', 'Limits', 'create', '0', '1014', '3'),\n      ('35', 'Manage Shadow Limits', 'Limits', 'edit', '0', '1014', '4'),\n      ('36', 'Manage Shadow Limits', 'Limits', 'delete', '0', '1014', '5');\n    go\n     \n    insert into [assignable_permission_set_item]\n    (\n        [assignable_permission_set_id],\n        [function_privilege_id]\n    )\n    values\n        (1, '33'),\n        (1, '34'),\n        (1, '35'),\n        (1, '36');\n    go\n    \nWhen you insert the applicable_function_privilege, the value of privilege_id should be id from the privilege table. The values are: 2- view, 3 - create, 4 - edit, 5- delete, 6- approve.\n\nAfter updating the database, restart access-control.\n\nThe values in these code examples are sample values only.\n\n#### 1. Follow the business function guidelines\nWhen adding a new Business Function it is crucial to follow the guidelines and naming conventions for adding a custom business function (on a Project). By doing so we can prevent disorganization, clashing with bussines function names used in the product and the breaking of current flows:\n\n| Parameter | Type | Length | Description\n|--- | --- |---| ---|\n| ID | String | 36 | Description: unique ID in the system \u003cbr\u003e  Guidelines: \u003cproject_prefix\u003e.\u003c1xxx\u003e \u003cbr\u003e Example: bankA.1000 |\n| Function_name | String | 32 | Description: name of the business function and unique in the system\u003cbr\u003e Guidelines: \u003cproject_prefix\u003e \u003cdescriptive name\u003e\u003cbr\u003eExample: bankA PISP|\n| Function_code | String | 32 | Description: Unique code used for internationalization on front-end (widget) \u003cbr\u003e Guidelines: same as function name in lower case, use dots instead of spaces \u003cbr\u003e Example: bankA.pisp \u003cbr\u003e On the front-end, you map this code with the descriptive name of the business function. For example, make payments from the business’s bank accounts using third-party websites or software. |\n| Resource_name | String | 32 | Description: Logical grouping of business functions (no real usage at the moment) \u003cbr\u003e Guidelines: \u003cproject_prefix\u003e \u003cgroup_or_business_function\u003e, if the business function is part of some logical grouping or use the same name as the business function. \u003cbr\u003e Example: bankA psd2, bank openbanking, bankA payments, etc. |\n| Resource_code | String | 32 | Description: Unique code used for internationalization on front-end (Widget) if required (for now we are not using this at all) \u003cbr\u003e Guidelines: same as resource_name in lower case, use dots instead of spaces \u003cbr\u003e Example: bankA.psd2, bankA.openbanking, bankA.payments |\n\n#### 1. Display custom business function name on front-end\nIf you skip this step in the procedure, there is a fallback mechanism in place, which will trigger displaying the business function name entered in the database on front-end.\n\n##### a. Modifications on the following extensions that display Business Function list is required:\n`ext-bb-sa-user-privileges-ng, ext-bb-function-access-groups-ng.` Add the following (example using the Manage Shadow Limits busines function) to the messages.json inside the assets folder:\n\n    manage.shadow.limits (function_code): \"Configure Shadow Limits\"\n    \n##### b. For the ext-sa-user-privileges-ng extension, additional step is required:\n\nIn templates/template.ng.html, find the ui-bb-permissions-modal-ng component and update the businessFunction object inside of data-labels directive with the newly added business function:\n\n    'manage.shadow.limits': ('business.function.manage.shadow.limits' | i18n)\n\n##### c. Business functions on the front-end are grouped based on the resource name. When a business function with a new resource name is added, by default it will be displayed in the group Others. You may configure the newly added business function to be displayed in one of the available groups, by referencing the resource name to the selected group by either of the following methods:\n\n-Update the constants.js file to include the new resource in a group (or creating a new group)\n\n-If you created a new group, update the messages.json file to add internationalization for the new group\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbackbase%2Fsample-service-with-access-control","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbackbase%2Fsample-service-with-access-control","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbackbase%2Fsample-service-with-access-control/lists"}