Tomcat web.xml: restrict access to specific methods of a servlet - java

I'm running a web application under Tomcat server. Different servlets are configured using Tomcat's web.xml.
I'm looking for a convenient way to restrict access to specific METHODS of specific URLS so that only these METHODS can be accessed using an Authorization header while others can be accessed without any restriction.
For instance, for url http://localhost:8080/my/servlet1 - GET and OPTIONS can be accessed by any user, while POST and PUT must be authorized with a username and a password, but for url http://localhost:8080/my/servlet2- all methods are open.
How can I implement that?
Thanks

The most low level API that allows you to do all sorts of filtering based on the context of the HTTP request in the javax/servlet/Filter
You implement a filter class that can restrict on the basis of HTTP method and any other criteria you choose. You register the filter on your web.xml and you add rules for which paths it is filtering.
Here is an walk through on applying such a filter.
If you happen to be using more than just a naked Tomcat for your application and you are using Spring Boot on top of it you could use their flavor of filters. This is an example for that case.

Related

Securing a jersey RESTful web service

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.

JSF2 - Flexible way on restrict access on certain xhtml pages, apply simple logic on access

Hi I am actually trying to get tips or ideas on a very specific problem. The technology context is
java web app with JSF 2.1 .
So I have a simple java ee app powered by JSF 2.1. The structure is the following
\webapp
\WEB-INF
\templates
header.xhtml
menu.xhtml
web.xml
\secured
\operation1
op1.xhtml
\operation2
op2.xhtml
\operation3
op3.xhtml
userhome.xhtml
login.xhtml
I have one #WebFilter that restricts the access to /secured/* in case the 'user' bean is not set (Actually a Session Scoped Bean).
At the same time upon login, I create a dynamic Menu depending on the user credential. this menu (MenuItems) point to one or more operations (xhtml pages).
So far so good, the user logins, the menu is dynamic, links are being generated and upon clicking he/she can navigate to whatever operations he/she is supposed to do.
My problem is that I can not decide on an elegant way on restricting access to the absolute url of these pages . If user1 is 'authorized' to execute operation1 but not operation2 or operation3, currently I can not find the most elegant way on checking his session state and applying a generic rule (navigation rule?), if the actual web user, writes on the url bar the absolute path of the operation.
'/secured/operation1/op2.xhtml'
What is the most JSF2 compatible way on achieve that kind of requirement?
I have tried the preRenderView on each separate opxx.xhtml page , unfortunately it did not work + i dont like repeating it on each operation
Many thanks for your tips.
Security in web applications is a more advanced topic. Basically you have two ways:
Container based: This means your servlet container like Tomcat does the job for you (recommended)
Application based: You have to do the job on your own
How to setup container based security is explained in detail here. To summarize it, you have to implement a simple form (no JSF form!) with a specific action and specific ids for the username and password field. Afterwards you can easily restrict access to specific URL patterns using your web.xml file. In the web.xml file you restrict access to certain URL patterns for certain user roles. The mapping from usernames to user roles is done by a security realm. How to setup a security realm is desribed e.g. for Tomcat here.
If you want to implement security on your own, you have to implement a ServletFilter that inspects all requested URLs and either forwards users that are not logged in to your login form or passes the request through if the user is authorized. If the user is not authorized to see the page, you will have to forward the user to your error page. As CDI injection does not work for ServletFilter, you will have to lookup the bean that stores the information about your user (logged in, rights) from the HttpSession.

Java webapps security constraints & custom security providers

I'm creating a restful web service using Resteasy. One thing I need to do is to secure the service using a standard HTTP auth request. The tricky part is that the service is multi-tenant and needs to use one of the path parameters to determine the security realm.
There are a lot of articles typical of this link which describe setting up a single-tenant service. What I can't find is what to configure, and what interfaces to implement to describe my own security which is based on a path parameter + the username in the HTTP authentication method.
I envision that prior to calling any of the application logic, tomcat/resteasy would call a SecurityProvider (or whatever) interface with the HttpServletRequest and have me either throw a 401 or return a SecurityContext that gets passed to the JAX-RS handlers. In that routine, I would inspect the path parameters, and make a determination based on parameter+username+password given in the Basic/Digest/Form.
Is there any such beast?
I thought I'd update this since there's bee little activity on this question.
It looks like there's no baked in feature to do what I envisioned, so instead I extended the RestEasy servlet and added the security checks in my override before passing control back to the stock RestEasy servlet.
Seems to work well.

Can Apache restrict access based on a Tomcat webapp's Spring SecurityContext?

We have a tomcat webapp which provides webservices which are protected using Spring Security. The client makes a call to a specific authenticationService method which we wrote to authenticate them and create an authToken which is then used to register them with Spring Security as so:
SecurityContextHolder.getContext().setAuthentication( authToken )
That's all fine and good. However, we also have the requirement that authenticated users be able to access static content which is served by Apache (httpd) on the same server. Is there a way to enforce the requirement that the user has been authenticated (by Java/Spring) before they can download the static content? It seems like Apache and Tomcat would have to somehow share the SecurityContext.
OR - alternatively it seems like Tomcat could serve the static content itself since it already has access to the SecurityContext. If that is the best solution, could anyone provide a pointer to how we would get tomcat to do that (serve static content after checking that the user has been authenticated).
Thanks.
Yes, Tomcat is going to have to serve the static content.
mvc:resources can be helpful here. After that is set up protect those mappings using the standard intercept-url configuration.

Websphere - What is the best way to hide wsdl's from end user?

I think there are several ways to hide wsdl's from end users for WebSphere (6.1). We use axis to publish Web Services and I currently updated the custom Servlet class (which extends AxisServlet) and override the service method to throw 404 error for urls like: http://xxxx/services/MyService?wsdl. The other option may be adding filters.
Are there any other alternative ways?
Thanks.
What lutz pointed to is correct. You should add some authentication mechanism to your SOAP interfaces if they can do something potentially harmful. However if you insist you can block the access to anything that looks like wsdl query, for instance with
Servlet Filter for your applications
Front-end web server configuration that will redirect those queries to somewhere else, ie.
RewriteEngine On
RewriteRule ^(.+)?wsdl$ /error.html

Categories