Identifying the calling code path for an API method - java

I am interested in finding a pattern or strategy for identifying which code path called a specific API method (or set of methods).
Here are some examples of differentiation in my application:
Caller calls API via an exposed REST controller
Caller calls API via some other internal API
Caller calls API via a user-created plugin
The application does use Spring for core wiring as well as Spring Security. However, the caller could be any user so using the Spring security context to inspect authentication or their associated granted authorities doesn't appear to be the right fit. The same user could call into the API method via one of the exposed REST URIs or call in via an arbitrary plugin entry-way.
How can one manage this type of identification without exposing additional or semi-duplicated APIs for different entry-points? I would like to be able to identify where a particular call originates. Slight differences in functionality can occur depending on whether the call came from one of our REST endpoints as opposed to one user-generated plugin as opposed to some other user-generated plugin.
This could hint at using some form of interception/aspect, but I do not have control over plugin code since I did not generate it. Plugins do have to register in order to get integrated so there is a programmatic hook there.
Looking for suggestions on how to manage this type of issue whether it's using additional Spring feature functionality or an alternative idea or library.

In fact this is a nice question.
As far as i see there are these options:
semi duplicated API (already mentioned above)
different users (or user-groups)
get callstack using reflection (but hard to do and not really recommended)
instead of user you can use some kind of authorization-token "per session" and see if the session is create via HTTP call or if it is an "internal" session
check some kind of session-id and save inside your session where it was created (internal or external, ...)
For now i don't see any other possibilities.
ps: to "flag" the session as internal/external can be done by adding an own spring handler.
Hope this brings you to the right point and helps you out.

Related

How to properly handle Cross Origin (CORS) for a Spring-based Rest API

I am working on an application with a completely decoupled front and back end. The front end has been implemented using Angular and the back end is implemented in Java using Spring extensively. Communication between the two is done via a Spring-managed Rest API. In addition to this, we have an external third party application(s) that also use this Rest API. So the API is used for two purposes: (1) as a "generic" API for an indeterminate number of clients and (2) as a very specific API designed specifically to meet the requirements of the Angular front end. We have separate Controllers to handle the separate concerns.
The problem I ran into was that of CORS. At the moment I have just annotated the Controllers with #CrossOrigin and that is fine for now but, I would need a more secure solution before we go live. I am aware that you can specify certain domains to limit when cross origin requests are allowed, however, that would not work for me. It would work if we just had the Angular front end to consider, but what about the external clients? There domains are not known. I almost need some sort of mechanism for the clients to authenticate and register themselves at runtime and then only these registered clients will be allowed to perform Cross Origin requests.
So that is what I am asking: given the above, what is the best solution to my problem? I need a solution that protects against Cross Site Request Forgery as well as meets my requirements stated previously.

Cross JVM instrumentation

I'm spending sometime with DynaTrace.
I'm impressed by its feature related to cross jvm instrumentation.
In simple words, DynaTrace is able to instrument Java code creating trace with some statistical information. This is nothing new.
There is a feature really interesting: when a call to an external JVM is execute, DynaTrace is able to link this new trace to the caller one (i.e. remote session bean, web services, remote RMI and so on).
How could it be possible?
I'm not able to immagine how to implement this feature? Any ideas?
Thank you
Dynatrace actually doesnt rely on information from beans. As you correctly said in your questions - we are using Byte Code Instrumentation such as other tools in the market as well. We instrument key methods of certain frameworks, e.g: Servlet, Axis, JMS, JDBC, ...
In the scenario where you make a call from one JVM to another using e.g: HTTP-based communication we instrument both the sending side of the HTTP Request as well as the receiving side on the other JVM. On the sending side we attach an additional HTTP Header with the ID of the current PurePath. PurePath is our patent technology. So - every PurePath (=every single transaction) gets a unique ID. This ID "travels" with the request, e.g: we put it on the HTTP Request as an HTTP HEader. ON the receiving side - your second JVM - we inspect that HTTP HEader and therefore know that all the data we collect belongs to that PurePath. This allows us to do real end-to-end tracing without relying on things like Beans or without correlating this data based on e.g: timestamps
Makes sense?
If you have more questions let me know. I also recorded some videos and put on YouTube to explain the technology and the product itself: http://bit.ly/dttutorials
This information is normally extracted using MXBeans. Such beans provide a standard API for accessing standard runtime information. Similarly, such applications often scan the class loaders for specific classes and extract relevant information by hard-coded access. This is why less popular solutions are often not supported by monitoring tools.

Passing in objects to GWT servlets via servlet attributes (server-side) or "Dependency Injection"

How do I pass objects from non-GWT server-side code (e.g. regular server code) to the GWT "servlet" (still server-side code), specifically a RemoteServiceServlet?
My GWT server-side code consists of RPC-type RemoteServiceServlets to which I can't seem to get a reference so I can't pass in my real/fake object in testing mode or add servlet attributes. I can't see any way to simply pass objects in (dependency-injection style) as I have no access to the Server object as GWT seems to instantiate it deep within its internals, so what are my options?
P.S. I don't want to use a full-blown DI framework such as GIN/Juice - I find them to much magic. I just want a way to access the instance of a GWT servlet and pass stuff to it.
Let me start out by saying, if you haven't already, I highly recommend watching this Google I/O presentation on GWT Architecture best practices. I found it very useful and it's where most of the following came from.
What I did was create an abstract "dispatch" servlet that extends GWT's RemoteServiceServlet. Every module I have has only one service (that extends my abstract dispatch service) with which I register a set of request handlers. All GWT service calls for a given GWT module come into that module's dispatch service, which looks at the type of request and dispatches it to the appropriate request handler. The request handlers, in effect, handle the work that previously resided in the service servlet. Besides making your life easier by having fewer servlets to register in your web.xml (not to mention avoiding the extra interfaces GWT requires), you can more easily control the dispatcher object that handles all the actual dispatching. You can, for example, pass whatever real/mock object you like into these request handlers since you, and not the web container, are responsible for instantiating them.
And though I rolled my own, the gwt-dispatch project exists for this very purpose.
Hope this helps.
Servlet containers are designed to not allow direct access to the servlets that they host; that's why you've found it difficult to get any kind of handle to a servlet.
Rather, refactor the code that is currently in your servlets into separate request-handler classes, and have your serlvets call into them.
For testing purposes you can hook your testing framework, or your client code, to the request-handler classes directly. That's how people generally solve the problem you've run into.

How to access the Principal from a Java service object without using FlexContext?

We're building some Java objects that are exposed via BlazeDS to our flex client application. So basically the BlazeDS messagebroker servlet instantiates and invokes methods on these objects in response to client requests. Works great.
We're using app server-based authentication and have set up a security constraint on the <destination> elements in the remoting-config.xml file element to prevent unauthenticated clients from being able to access these remote java objects. Again, works fine.
However, there are several places within the implementation of these java objects where we want to get the currently logged on user's username. Right now we are doing this via FlexContext.getUserPrincipal(), which gives access to this but we have a nagging concern that we don't like the idea that the implementation of these objects (the service layer) has a hard dependency on a BlazeDS class. But we're not sure how else to get access to this. The same applies to accessing the ServletContext and such.
Any ideas?
There isn't a way around this when using BlazeDS's MessageBrokerServlet. The only option I can think of is to write your own servlet that does AMF, like this one.

Permissions checking in server-side API

our product is built on a client-server architecture, with the server implemented in Java (we are using POJO's with Spring framework). We have two API levels on the server:
the external API, which uses REST web services - useful for external clients and integrations with other servers.
the internal API, which uses pure Java classes - useful for the actual code inside (as many times the business logic invokes an API call) and for integration with plusins developed inside out company and deployed as parts of our product. The external REST API also uses the internal API.
We implemented permission checking (using Spring security) in the internal API because we wanted to control access at the lowest API level.
But here comes the problem: there are some operations defined on the API level that are regarded as forbidden for a currently logged user, but which should be performed smoothly by the server itself. For example, deleting some entity could be forbidden for the user, but the server might want to delete this entity as a side effect of some other operation performed by the user and we want this to be allowed.
So what is the best approach for allowing the server to perform an operation (in some kind of super-user mode) that might be forbidden for the actual logged-in user?
As I see it we have several options each of which have its pros and cons:
Implement permission checking in external level API (REST) - bad because plugins will bypass permissions checks.
Turn off permission checking for the current thread after the request was granted - too dangerous, we might allow too many server actions that should be forbidden.
Explicitly ask the internal API level to perform the operation in the privileged mode (just like PrivilegedAction in java security framework) - too verbose.
As none of the above approaches is ideal, I wonder what is the best-practice approach for this problem?
Thanks.
Security is applied at the bounds of a module. If I understand you, your system applies security on two levels of abstraction of the (roughly) same API. It sounds complex, as you have to make a double security check on the whole two APIs.
Consider migrating the REST needed methods from the internal API to the external one, and deleting security stuff in the internal API.
external API will manage security for external clients (at the boundaries of your app)
internal API will be strictly reserved for internal app and plugin use (and you would happy hack it, as no external clients are bounded to it)
Do you really need to control the plugin's permissions to your application logic ? Is there a good reason for it ? Plugins are developped by your company, after all. Maybe a formal document explaining to plugin's developpers what should not be done, or a safety test suite validation for the plugin (e.g. assert plugin does not call "this" method) will do the job either.
If you still need to consider these plugins as "untrusted", add the methods they need to your external API (on your app boundary) and create specific security profile for each use: "restProfile", "clientProfile" & "pluginProfile". Each will have specific rights on your external API methods.
It sounds like you need two levels of internal API, one exposed to plugins and one not.
The best way of enabling that would be using OSGi (or Spring Modules). It allows you to explicitly state which packages and classes can be accessed by other modules (ie REST modules and plugin modules). Those would be the exposed level of your new internal API and you would use Spring Security to further restrict access selectively. The internal packages and classes would contain the methods which did all the low level stuff (like deleting entities) and you wouldn't be able to call them directly. Some of the exposed API would just duplicate the internal API with a security check, but that would be ok.
The problem with the best way is that Spring Modules strikes me as still a bit too immature even to put into a new webapp project. There's no way I'd want to shoehorn it into an old project.
You could probably achieve something similar using Spring Security and AspectJ, but it strikes me that the performance overhead would be prohibitive.
One solution that would be quite cool if you could re-architect your system would be to take tasks requiring security elevation offline, or rather make them asynchronous. Using Quartz and/or Apache Camel (or a proper ESB) you could make the "delete my account" method create an offline task that can at a future date be executed as an atomic unit of work with admin priveliges. That means you can cleanly do your security checks for the user requesting account deletion in a completely separate thread to where the deletion actually takes place. This would have the advantage of making the web thread more responsive, although you'd still want to do somethings immediately to preserve the illusion that the requested action had been completed.
If you're using Spring, you may as well utilize it fully. Spring offers AOP that allows you to use interceptors and perform these cross-system checks, and in the event of an unauthorized action, prevent the action.
You can read more about this in Spring's online documentation here.
Hope this helps...
Yuval =8-)

Categories