Issue
- We developed a REST service and it works. But we need endpoint security. At the moment it is available without any credentials.
- We do not want to give access to a REST Web service without credentials.
How can we force user to send credentials (Basic Auth is ok) to call our service Endpoint?
Environment
- Liferay DXP 7.0
Resolution
We'll show you how to implement a simple User-permission layer using the https://github.com/liferay/liferay-blade-samples/tree/7.0/liferay-workspace/apps/rest sample project.
- When you build and deploy (
liferay-blade-samples/liferay-workspace/apps/rest{7.0}$ ./../../../gradlew deploy
) this module and visit http://localhost:8080/o/com.liferay.blade.rest/users/list : you'll get back the list of users:
Test Test
- Let's update the related method of UsersRestService.java to look like this:
@GET @Path("/list") @Produces("text/plain") public String getUsers() { PermissionChecker permissionChecker = PermissionThreadLocal.getPermissionChecker(); if (!permissionChecker.isCompanyAdmin()) { throw new WebApplicationException(Response.Status.FORBIDDEN); } StringBuilder result = new StringBuilder(); for (User user : _userLocalService.getUsers(-1, -1)) { result.append(user.getFullName()); result.append("\n"); } return result.toString(); }
As you can see, we're getting the PermissionChecker and checking if the given user is Company Admin. If not, we throw a standard exception that is allowed from JAX-RS applications. (You can google for more details on exception handling).
- Redeploy the module and retest. If you visit http://localhost:8080/o/com.liferay.blade.rest/users/list again, you will get back an empty response and HTTP 403 status.
-
Let's test the service invocation with Basic Auth:
- Encode "test@liferay.com:test" with base64: base64 <<< test@liferay.com:test : Result: dGVzdEBsaWZlcmF5LmNvbTp0ZXN0Cg==
- Invoke the endpoint:
curl -H "Authorization: Basic dGVzdEBsaWZlcmF5LmNvbTp0ZXN0Cg==" http://localhost:8080/o/com.liferay.blade.rest/users/list
Result:
Test Test
- Repeat the same with a non-omniadmin user: you'll get back an empty response as expected.
-
Basic Auth is enabled for this application here: https://github.com/liferay/liferay-blade-samples/blob/7.0/liferay-workspace/apps/rest/src/main/resources/configuration/com.liferay.portal.remote.cxf.common.configuration.CXFEndpointPublisherConfiguration-cxf.properties#L2
- Similarly, if you want to be able to access the endpoint from your browser with an authenticated user through your session, you can
A.) Go to System Setting > Foundation > CXF Endpoints > /com.liferay.blade.rest > and addauth.verifier.PortalSessionAuthVerifier.urls.includes=*
or
auth.verifier.PortalSessionAuthVerifier.urls.includes=/users/list
to the "Authentication Verifier Properties" so you'll have both Basic Auth and Portal Session auth verifiers enabled for the sample service.
auth.verifier.BasicAuthHeaderAuthVerifier.urls.includes=/users/list // or simply "*" auth.verifier.PortalSessionAuthVerifier.urls.includes=/users/list // or simply "*"
B.) Add it to the configuration files of the "rest" sample module
C.) Go to System Setting > Foundation > Portal Session Auth Verifier: and add "/users/list" to the "URs Includes" property
- Similarly, if you want to be able to access the endpoint from your browser with an authenticated user through your session, you can