Scenario
I'm writing a small health check module (jar) that allows users to retrieve information via a JAX-RS REST service. Other applications that use JAX-RS can import this module and benefit from it. The module will use the JAX-RS implementation defined by the consuming application.
Problem
I want to be able to run the health check module on a different port. This will allow us to easily block access to it via the firewall. Is it possible to have multiple ports that server HTTP requests? If so can I map these to different JAX-RS Services easily
If I can't get around this I have been thinking about embedding a small http server into the health check module.
I'm not familiar with TC Server, but since it's based on Tomcat (AFAIK), you could try to configure an extra HTTP Conector for your custom port (http://tomcat.apache.org/tomcat-6.0-doc/config/http.html). The problem then, is that your JAX-RS endpoints may allow incoming requests on both ports, so the problem remains the same. Then you could also add a Valve (http://tomcat.apache.org/tomcat-6.0-doc/config/valve.html#Remote_Address_Filter) to filter clients based on their IP Address. All this is server configuration, not something based on your module, though.
But IMHO, the cleanest and safest solution would be to secure your JAX-RS Endpoints with authentication mechanisms (your data should be encrypted over an SSL connection anyway).
Related
I’m wondering what the best practice is for only exposing certain APIs on a SpringBoot service. For context I have a service that will be sitting behind a TCP load balancer which has some apis that will be called from a web page. However, I’d like to limit which APIs are exposed, like a metrics scraping endpoint for Prometheus and some other actuator type endpoints.
I was thinking of standing up an NGINX instance on each service host and proxying requests to the instance on the same host. In that way, I think I could limit which APIs are available publicly. But I’d like to know what other options are recommended or available.
As it turns out, Springboot has a configuration that allows you to expose the actuator endpoints on a different port. Using Spring boot version 2.7.X I was able to do the following:
management.endpoints.web.exposure.include=health,prometheus
management.server.port=9090
Changing this port does not affect the normal server port that http requests are served from.
Grpc Server seems to be implemented using netty. Is there a way to use other implementations ?
Netty is the only supported server. You can either have two separate ports (one for your other server, one for gRPC) or could reverse proxy from your other server to the Netty server.
There is work underway (tracking issue) to allow serving using the Servlet API, so then any Servlet Container could be used. But there are restrictions, like the needing to be the root ('/') webapp. It is far enough along to test it and provide feedback, but there also may be some gaps in the implementation.
I have separate application for client side which is in ReactJs and NodeJS (Express server) and Web Services in Java application running in tomcat.
My query is which is better approach in terms of making web service call.
One is making direct web service call from ReactJS and get the data.
Other one is calling web service in Express server. Request from client browser will go to Express and Express will make all web services call.
I know one issue in making direct call to web service will be cross domain policy which can be handle by setting configuration in Java server.
Apart from it what should be better approach.
From my experience it ended up better using direct calls from UI application and avoiding intermediate server.
Reason for doing this directly is that our servers ended up with a lot of restrictions based on IP addresses, and all requests have been coming from intermediate server (nodeJS server), so DDOS protection of end server had to have some exceptions (our node server which could be on ACS with dynamic IP addresses so it might be hard to manage).
Also If you want to pass and track end users IP addresses, you need to manage headers on Node server (to be sure you are passing it as it was in original request).
It is way simpler to manage this kind of situation if calls are comming from React app and simply set up CORS on java server.
Also its way easier to debug it on UI app directly, so you will be watching response logs on one place only. Other way around you could end up debugging your node server and UI app.
Hope this helps a bit.
Best way IMO is to create a router in Node js specifically for all your Java webservices and act as a proxy.
Suppose if your url pattern is like http://domain/java-ws/api then all these requests will be routed to your Java service.
If you have an Apache server directing requests to your node JS then configure url pattern proxy using proxy module.
Browsers are blocking CORS requests for a reason. You may get away by setting things on your server.
Case:
Developing a standalone java client which will run on different locations on multiple user desktops.
Application server(Oracle Weblogic) will be running at centralized location in different place.
Now I want to access/call EJB (Session Bean) running on central server from client.
As client and server are on different location and not connected via Intranet or LAN only medium of connection is internet.
My question is how can I call EJB's in server directly from client without using a servlet/JSP layer in between?
EJB was devised for remote access , why a servlet dependency?
I have read that RMI-IIOP can be used to make this type of connection but I am unable to use RMI-IIOP over internet!
What is the best architecture/solution for this type of remote communication?
Remember that the EJB is a consise unit of buisness logic, they are protocol agnostic. Exposing it to the caller is the job of the application server. RMI-IIOP/CORBA is just the default.
The internet routing issue with IIOP is similar to many protocols, it is not that they don't route over the internet, it is that they do not have an easy proxy / reverse proxy feature built in. Hence has issues going through a DMZ. Compared to HTTP which has support for reverse proxy, or SMTP allows for relaying. The firewall port is typically closed as well, You would not normally put an application server in a DMZ.
To solve the problem of giving direct access to business logic to an external network, i typically change protocols to something designed for external network communications. For example, annotate (or deployment descriptor) the EJBs with the #WebMethod and the become available as SOAP services automatically, or use the #PATH (etc.) to expose them as HTTP/JSON/XML services.
CORBA type protocols have out-of-the-box features for security, XA transactions and are very high performance. I usually use this for enterprise level component oriented systems internally. (each EJB component is essentially used as a microservice) While for external integration, especially where the caller does not need to pre-know the interface contract, I typically go with a SOAP or HTTP/JSON/XML endpoints for the EJB.
There is no servlet dependency. There is a custom client/protocol dependency that's app server specific. Each server has their own way of setting up the connection, manifested through configuring JNDI for the proper providers and protocol handlers.
Why won't RMI-IIOP work over the internet? The only potential issue I can see there is security, I don't know if there's an encrypted version of RMI-IIOP or not, but other than that, it's a perfectly routable protocol.
You may run in to port and firewall issues, but that's not the protocols fault. If you want to run RMI-IIOP over port 80 (http's port), then that's fine (obviously it won't be http, nor work with http proxies, but again, that's not the protocols issue).
Weblogic also has (had?) their own protocol, T3? I think it was? Can you use that?
I think the key is why you don't think you can run RMI-IIOP "over the internet", and trying to solve that problem, not necessarily what protocol to use.
The RMI/IIOP is the default provided by the application server. By configuration / annotation SOAP or HTTP/XML/JSON can be used instead. (Although these protocols have some trade-off with security, transactions, etc.)
Well EJB doesn't have at all a dependency on the servlet. They can be called directly using RMI/IIOP.
The only problem you have to face is the network structure, i mean RMI/IIOP uses some ports that usually aren't open in company Firewall and it could be quite difficult to open them.
So usually it is better to make an HTTP request because almost all firewall accepts this kind of request.
So if you are in an intranet (client and server in the same intranet) you can use RMI/IIOP but if your client and server are placed in different networks with internet connection then i suggest to you to use HTTP.
You could use Webservices and "export" your EJB as a web service.
If you don't want to use Webservices then you could implement as extrema-ratio a servlet that receives HTTP request and calls the EJB. It depends on the type of object you have to return to the client.
If it is a simple string or something not too complex then you could even use a Servlet but if they are objects then the Servelt solution isn't the right choice.
We are looking at building an application that either proxies a standalone LDAP server or delegates to an embedded Java LDAP instance (ie: ApacheDS, OpenDS) in order to log requests and determine who is accessing which applications on our very large corporate network.
My question is is there a good way to intercept an LDAP request and "pull it apart" or have either OpenDS/ApacheDS push notifications of requests coming into LDAP.
You don't need to do any of that. You can configure LDAP servers to log accesses, either in the LDAP directory itself or elsewhere.
OpenDJ (the actively developed fork of OpenDS, http://opendj.forgerock.org) has support for multiple and customized access logs, so you can even configure some filters for the specific requests you're interested in.