I am new to Java so apologies if this is a simple thing. I have built decorators in Python for authorizing RESTFul endpoints in Flask and have just built my first Java Webserver but am unable to figure out how to create a similar decorator in Java.
I want to do some pre-checks before running the method (i.e. is the user allowed to access this route). Ideally this would be a decorator like #authorize that, if authorized, will execute the method, but if unauthorized then it would through a 403 error instead.
#Path("/")
public final class HelloWorld {
#GET
#Path("/hello")
#authorize // How would I implement this?
public String sayHelloWorld() {
return "Hello World!";
}
}
EDIT: I am using Grizzly as the web Framework and I will be using an external Policy Management System (Apache Ranger) for managing authorization.
First of all: defining such custom annotations is exactly how you can approach such things in Java. The JAX-RS specification provides all the things you need for such kind of method binding.
The thing that is slightly more complicated: how to nicely do that for the framework that you are using.
With JAX-RS and Jersey for example, creating your own annotations is well documented. And Jersey might be a good starting point, as that is simply a straight forward way to get JAX-RS working.
So, first you start by learning how to use Jersey in general, for example from vogella. Next: you can start to add your custom annotations, see here for an example.
There is even an existing question about using custom annotations for access validation.
Related
I'm developing a restful web service that will be consumed by an Android application later on.
Right now, I'm seeking a way to secure the access to my resources:
I found several ways for implementing that on the net, but I can't figure out what is the most appropriate one.
For example, I found that Oauth specifications are more convenient for third-party applications which is not my case.
So what are the most suitable ways for securing jersey APIs, and I'll be glad if someone can provide me with any tutorials/documentations on that.
I'm using a Glassfish v4 server and the Jersey JAX-RS implementation.
After looking at different options I used an authentication filter and basic auth. Very easy to implement.
Some example code:
You need a filter
public class AuthFilter implements ResourceFilter, ContainerRequestFilter {
...
}
And a security context:
public class MySecurityContext implements SecurityContext {
...
}
And a user class:
public class User implements Serializable, Principal {
...
}
Finally, you can add the filters you need like so: (pass your ResourceConfig object to this function)
private void prepareFilters(ResourceConfig rc) {
rc.getProperties().put("com.sun.jersey.spi.container.ContainerRequestFilters",
getClassListing(new Class[]{
AuthFilter.class
}));
rc.getProperties().put("com.sun.jersey.spi.container.ContainerResponseFilters",
getClassListing(new Class[]{
CORSFilter.class, //You might not need this
GZIPContentEncodingFilter.class //You might not need this
}));
rc.getProperties().put("com.sun.jersey.spi.container.ResourceFilters",
getClassListing(new Class[]{
RolesAllowedResourceFilterFactory.class
}));
}
BTW, you can add #Context SecurityContext securityContext; to your resource class(es) or the individual methods for more fine grained access control. The SecurityContext will be injected into the context of your resource so you can access the User object per request with
With this setup you can annotate your REST methods with #PermitAll, #RolesAllowed, etc which gives you a good level of control over your RESTful interface.
I just finished my stateless (without sessions) user auth and management with Jersey.
Let me know if you want a full example or if you want to give it a try yourself ;)
The simplest way would be using the Java EE build-in Container Managed Security model to secure your rest resources as described in this tutorial. It allows you to configure the security based on users and roles stored in a database or file realm in the web.xml or the the classes themselves.
The disadvantage would be that you must start a session, extract the JSESSIONID and send it in each of your requests so that the server can verify it, but that makes your services more 'stateful' and violates the statelessness of the rest architecture.
Another way would be implementing custom security by using WebFilters, like sending the user name and password with each of your requests and verity them based on the information in a special db. If the information doesn't match the information stored in the database a redirect or a special error code can be returend in the Response object.
The best approach I think is using OAuth2 as described in this specification. Dependend on what kind of client you are using (desktop, web page, mobile client) there are different workflows and apart from that lots of benefits like creating tokens for special scopes of your application (read-only or full access,...). Google provides many different apis that can be accessed by the same account. If an applications only needs data from the calendar api, the requested token only gives you access to this special api and not to the entire resources of the account (like mail data, notes, etc). Another point would be that the security handling is decoupled from the client and no password must be stored in the client application.
You can either implement everything on your own or use a open source project like this. It provides a description on how it works and the code is very good but it has many dependencies to spring frameworks. For my use case I've startend replacing them by vanilla Java EE 7 code and create a solution based on the idea of this open source project. The reason behind the replacements was that it's more future-proof and it avoids class loader problems during the deployment.
In the Android app a Authenticator can be implemented for secure storing of the token.
I am in a situation where I have a nascent rest api architecture where each method has tons of ceremony (validation, db connection acquisition/release, authentication), raw request/response objects as the parameters, and hard-coded json strings as the output. I want to use spring mvc to help with at least some of these issues (auth & db stuff i'll need to hold off on). This would render a lot of the current architecture unnecessary. This is pretty easy except for one feature of the current architecture: dynamically adding api calls.
The entry point (servlet) for the architecture reads from an xml file that contains the path for a request and a corresponding class to load. The class must implement an interface that contains an 'execute' method which has the logic for the request. The servlet calls this execute method after loading the class. This allows dynamic extension of the api as follows. The app is packaged as a jar together with the associated config (xml) files and given to a client. The client includes this jar in his project, creates a class that implements the aforementioned interface, and adds a mapping from request url to that class in the included xml file. He then runs the app and gets access to both the original api and his custom api.
Example:
Client is given app.war, interface.jar and custom-mappings.xml. app.war contains the implementation of the core api (rest webservice), and interface.jar exposes the interface BaseController that has the method 'execute' (app.jar also uses this interface in its controller). Client then defines his own class as follows.
package custapi.controllers;
public class ExtendedController implements BaseController {
public void execute(HttpServletRequest request, HttpServletResponse response) {
// LOGIC
}
}
He compiles this class and adds it to app.war. Next, he updates custom-mappings.xml with the following entry.
/custcall/mycall
custapi.controllers.ExtendedController
He then deploys the app. The controller provided with the core api receives the request /custcall/mycall, looks it up in custom-mappings.xml, finds the class is custapi.controllers.ExtendedController, loads that class, and finally runs its 'execute' method. This allows the logic defined by the client to be run.
Ideal:
Current architecture is replaced with spring-mvc. That is, there is no more 'super' controller that parses requests and delegates to the appropriate class and, finally, method. Spring handles this. For the app that uses this new architecture, the client would receive the app.war and the spring mvc deps that expose controller annotations. The client would then create a new spring mvc controller (taking advantage of validation, parameter -> pojo mapping, object -> json conversion), compile it, and add the resulting class file to app.war. His controller would then become an extension to the core api exposed by the app. When the app is deployed, he would be able to make a request /custcall/mycall like before and have it execute the logic he defined. This ideal scenario allows clean code for the core api (which I and others programmed) and an extended api. (A downside to this approach is that the client is tied to spring. In an even more ideal scenario, the client would use framework-agnostic annotations which are mapped to spring annotations by the app. I'm not sure how easy this would be.)
I'm not sure how the above would be realized with a spring-aware controller without sacrificing the benefits of spring. I don't believe the client could simply define another spring-aware controller (correct me if I'm wrong on this). The only solution I can think of is to have a spring-aware controller that has a wildcard path (e.g., /cust_rest/*) which acts exactly the same as the current controller. The client would not get any advantages that spring has to offer, but the core api would be a lot cleaner. I was hoping there was a better solution, however. Ideally the client would get the benefits of spring without having access to the core api source code. Any ideas on this, or is my solution the best that can be hoped for?
Thanks.
(NOTE: For both scenarios, I am only guessing how the client actually gains access to the dependencies/interfaces and deploys. I have only had access to the core api project for one day, and so my understanding of it is not complete.)
Related: Runtime loading of Controllers for Spring MVC and dynamically mapping requests/URLs
The above question looks pretty similar to mine. Replies are sparse (second one is just off topic, I believe).
Provided you setup classpath scanning properly there's no need for interface. Your clients can just annotate classes with #Controller #RequestMapping("/foo/bar"). Even if this class is located in its own jar it will still be scanned. If this is a REST service consider using #RestController instead to avoid having to place #ResponseBody on each handler method.
Use spring security to do declarative authentication & authorization (what you're doing now is programmatic security)
I have been looking for a few days at tutorials on this subject but either they aren't exactly what i'm looking for or I cant get them to work. I cant imagine that more people aren't confused on the subject so I will ask here.
What I would like to create is a REST service in Eclipse that I can run on my web server and "connect to" using ajax from a separate dynamic web project. All i'm looking for here at the moment is a simple hello world example of a service returning ajax working alongside a separate web project that consumes the JSON it returns.
Im hoping to get a usable user guide (or at least links to one) that will help me out and future people looking for this same thing.
I have gotten as far as this simple class (i have included Jersey Jars but I dont understand what to do from here):
public class UserRestService {
private static final Logger log = Logger.getLogger(UserRestService.class.getName());
private CreateUserService createUser;
#POST
#Path("/CreateUser/{name}/{age}")
#Consumes("text/html")
public User createUser(#PathParam("name") String name, #PathParam("age") Integer age) {
return createUser.createUser(name, age);
}
}
How do i get this class to be an accessible api service on my tomcat server? How do I setup another web project to consume it (I understand how to make an ajax call this is more a question of how do i setup the projects)? Where do servlets come in ?
Rather than copying jars, it would be better to use maven or gradle for package management. A simple pom.xml (maven) with the dependencies can help you abstract determining the compile and runtime dependencies.
Okay so the Java standard is jaxrs (https://jax-rs-spec.java.net/). You can use Jersey which is the rest implementation of jaxrs (https://jersey.java.net/).
A sample of implementing a service using eclipse, jersey and tomcat can be found here: http://www.vogella.com/articles/REST/article.html
If you are feeling like an adventure you can look at vertx.io (http://vertx.io) and my beta release of jaxrs 2.0 framework for vertx called 'vest' (https://github.com/kevinbayes/vest)
Addition:
Jersey provides examples on github of how to implement services at https://github.com/jersey/jersey/tree/master/examples
I have a bunch of RESTful web services(80) with #GET and #PUT methods. I want to add an #OPTIONS method to each service. Instead of manualy writing #OPTIONS method for each service I want to be able to inject them in the services. What is the best way to do this?
I don't know exaclty your environment, but i think the best way in technologies I use is to specify the "auto-scan" property in the configuration file, the declaration of this property differs a little from a technology to another one, but the idea remain the same : all componants are scanned at the beginning of deploiment
sorry for my english :) but i hope this response helps you
From what I know of MVC outside of the Java world (PHP and Ruby on Rails), all requests are first sent to the front controller (or dispatcher... or boostrap, etc.), and the front controller looks to the request path pattern in the URL in order to determine what class/method should handle the request. In Java MVC, it appears that servlets are mapped with the url pattern in the deployment descriptor (web.xml), but the file extension and url pattern doesn't appear to be very flexible. Are there any Java MVC frameworks that use a front controller to read the request path exclusively to determine what classes should execute? Would it be fairly easy to hack Spring MVC to do this? Any examples? Thanks!
An example of one tool that works as you desire is web4j.
By default, it maps incoming URLS to the Action class whose package-qualified name maps in a fairly natural way the the incoming URL.
Example from its docs:
Request URL: 'http://www.blah.com/fish/main/member/MemberEdit.list'
Extracted part of URL: '/main/member/MemberEdit'
Maps (by default) to the Action: 'hirondelle.fish.main.member.MemberAction.java'
This is an example of how that particular tool performs the task. Since this is such a basic feature of web apps, I would imagine that nearly all such tools have similar mechanisms.
I am not a big user of Spring, but I can see from its docs that it has a number of ways of mapping requests to Actions :
SimpleUrlHandlerMapping
ControllerClassNameHandlerMapping
Java servlet mappings can also be by file extension.
Much like many non-Java frameworks, you could map all requests to a single servlet that then processes them but that tends to be discouraged in Java. It's certainly possible though.
If you want more REST-style URLs where you declare the mapping of path elements, you might want to look at the Spring MVC setup in Spring 3.0.
I agree the URL mapping is not very flexible but you can handle mapping with URLRewriteFilter
http://tuckey.org/urlrewrite/
For this purpose, the filter works almost like a controller.
Check out stripes:
http://www.stripesframework.org/display/stripes/Quick+Start+Guide
I've been looking at it as a possible upgrade from struts. There is an example on that page that is very similar to the web4j example given by John O.