Can the ResourceLocalService be called remotely vi

2019-06-14 14:03发布

I'm trying to create a Liferay permissions resource using the JSON-WS API. I haven't found any JSON-WS API registered service methods in http://localhost:8080/api/jsonws for creating Resources.

According to the JSON Web Services docs, you can remotely enable services by adding the @JSONWebService annotation. It is not clear to me how and if you can register Liferay's built-in services if they aren't already exposed.

Also, the Javadocs for ResourceLocalService specifically state:

This is a local service. Methods of this service will not have security checks based on the propagated JAAS credentials because this service can only be accessed from within the same VM.

So is it even possible to access methods of ResourceLocalService remotely with the JSON-WS API? If so, can you point me in the right direction of how to do it?

PS: I am successfully using the JSON-WS API in my external application for service methods that are already published and listed in http://localhost:8080/api/jsonws

2条回答
女痞
2楼-- · 2019-06-14 14:50

The approach I've used for this is to write my own service that has no data tables, but exposes some JSON WS methods. You do this in a plugin project using service builder's option for creating remote services (I used a portlet plugin because my app has portlets in it, but I believe it could be done in a hook plugin just as well).

Quick excerpt from a service.xml:

 <entity name="UserNotification" local-service="true"
    remote-service="true">
 </entity>

No fields, no finders... just the entity name.

Then in your plugin project's UserNotificationServiceImpl you create the methods you want to expose and make regular service calls to the Liferay service in question (you are responsible for making use of the permission checker, there's nothing automatic about security here). When you re-build your services ServiceBuilder reverse engineer's your methods and creates the remote service API.

The tricky bit is to then call your custom API, which will have a different form than the calls you make to the built-in API. Assuming you want the service to require authentication and give your method a user context to use with the permission checker you make the call in this form:

https://user:passwd@example.com/api/secure/jsonws/plugin-name.entity-name/method? ...parameters

There are other calling formats, but the key thing is that you address Liferay directly, and then identify the plugin and entity using that dotted notation. If you address your plugin in its own application context

https://user:passwd@example.com/plugin-name/api/secure/jsonws/entity-name/method? ...parameters

You will not get the authentication context, so you won't be able to use the permission checker. Unfortunately you will find a fair amount of material laying around the Liferay site that tells you to make the call this way. Don't.

I haven't addressed all details (configuration settings, calling nuances, etc) But the new documentation in the Developer Guide addresses them fairly well now. So be sure to study that.

You will also want to read up on Service Builder.

But be warned -- you are probably used to using the API page provided by your portal as a reference for the services. This fine for in-built services, but for services provided by plugins, this page is not reliable, as it gives incorrect examples. Go by the docs.

查看更多
叼着烟拽天下
3楼-- · 2019-06-14 14:52

In Liferay - as you point out from the documentation excerpt - *LocalService is only available from the same VM. Services that are available from remote are just *Service (without the Local part) and their implementations are supposed to check permissions, then forward the call to the *LocalService if applicable.

It wouldn't make sense to just add a Resource to Liferay without an actual object, so the ResourceLocalService is supposed to be called by the service that adds another entity (the Resource needs an additional object reference for the actual object, consisting of class name and primary key)

查看更多
登录 后发表回答