Typically in any web application, the major security concern is securing the resources from the malicious users who are trying to access un-authorized resources. They can change a value in the request parameter and try to access something that doesn't belong to that particular user.
For Example:
http://blah.com/id=foo
a user can change this to http://blah.com/id=bar and try to access the bar resource to access it.
With restful services this may lead to greater security concerns as the restful URL's are rather self explanatory.
eg:
http://hotels.com/hotels/1
a user can easily guess and change the id to 2 to see the details of it..
One design is to check at every request manually to see the access rights for the resources and deny it if needed.
but this is a cumbersome and not maintainable.
So the question is "Is there any tool/framework that can help achieve this in a easy manner? I know spring security supports static rules not dynamic.
Over the last couple of years, the de-factory standard for this has become Spring Security. This sits in frotn of any old java webapp (not just Spring webapps) and provides an interception authentication and authorization layer of your choice.
It's very powerful, although also rather complicated (over-complicated, IMO).
I would highly recommend looking into Seam Security. It can even be tied into a rules system.
edit: I believe you would need the Seam Core package for this to work. However, I have never tried using it without Seam, so I can't be positive about its dependencies.
Related
I have a somewhat monolithic Java application, built around Spring #Service beans for my business service layer. As a rule, each of my business service methods has Spring Security annotations (e.g. #PreAuthorize) to enforce appropriate authorization rules for that action.
Within the main web application flow, this works very well; each web request implicitly has authentication handled by session cookies, etc.
However, when it comes to various integration points with other, "internal" systems, I'm not seeing as clear of a solution.
For example, I am going to be consuming methods from a JMS queue, which already has its own authentication & authorization rules defined within the broker, so I want to implicitly "trust" the messages that I get. However, as things stand now, a simple enough Camel route like this:
WidgetService widgetService = lookup(WidgetService.class);
from("activemq:newWidget")
.unmarshall(...)
.bean(widgetService, "newWidget");
ends up throwing a AuthenticationCredentialsNotFoundException.
This tells me that Camel is calling my bean correctly, with all of the magic AOP applied from Spring.
With other things of this sort, I've resorted to applying AOP advice around the entry point for the system (e.g. around a Quartz Job's execute method), which injects a PreAuthenticatedAuthenticationToken, but I'm not sure if that's really the best approach.
Should I continue to wrap these "trusted" entry points in advice to add an Authenication context, or should I change my service layer to have special forms of some business methods which require no authentication, and just make sure I document clearly that they are not for use in web #Controller methods, etc?
Unfortunately there is best way to do that. It depends on the application and in my experience all solutions work but have some drawbacks.
The first solution would be to move the #PreAuthorize up to the web level. This way you will be free to use your services internally as much as you want. I think this is the simpler solution and easier to comprehend. You want to secure your web users right? Why not apply the security to in the web layer. The problem with it is that web layer changes more often than the business layer and it is easier to leave security breach if you don't develop your controllers and endpoints carefully. I would still take that approach for most applications and let the service layer take care just of business rules and not security (which is kind of business rule too? ). Of course you can still add some default security logic to groups of controllers and stuff so you don't have to repeat yourself everywhere.
The second approach is the one that you have taken. Run such methods in authenticated context which you generate. And it is a bit counter-logic - why to run in authenticated context when there is no authenticated user? You shouldn't have to do it but unfortunately that's the only way if you want to have secured services. This methods is less prone to security errors and you can maintain the security easier. If you stick to that you can use the template pattern or create some executor class that runs stuff in context.
I cannot think of a third approach :)
Here's my situation: I'm running a JBoss 7 in Domain Mode with several nodes. One node is in charge of my Liferay 6.2 another one runs several other web applications. Now I'd like to implement some kine of Single Sign On routine. So to use my web applications you have to go through liferay first. Authenticate agains liferay, then go one to one of the web applications.
So the question is whether there is a way to expose some of liferays methods to access the user store and check if the user, who's accessing a web application is the same as logged in on liferay. Developing some sort of bridge is fine with me. I'm thinking of a portlet which does all the interaction with liferay and exposes some methods like readUser(). Maybe I can do a jndi lookup for this portlet or a component embedded in this portlet to call readUser() from my other web applications. I think this sounds a bit like EJB stuff.
Using Liferays API, Services and LocalServices to read user information etc. shouldn't be that difficult (already played a little with that). I just don't know how to establish a communication between a web application and liferay.
If it's not working this way, I would settle for something else, maybe a webservice or an other way that makes sense but I'd like to try the EJB/JNDI approach first (except this makes completely no sense). Maybe someone can point me in the right direction.
Turning my applications into portlets is not really an option because these applicaions are quite large and already exsist for quite some time. So I'd like to leave them mostly unchanged - outside of auth stuff.
Thanks and regards
Sebastian
You can use a service builder and you expose your service as remote.
Several Options:
Just access Liferay's API methods from your applications. You can access the JSON API at http://www.example.com/api/jsonws.
There's also a SOAP interface (http://www.example.com/api/axis), that's typically available only from localhost (you can configure otherwise in portal-ext.properties)
You can encapsulate calls to those services by creating your own services. Use the tool of your choice or Liferay's servicebuilder. You can create empty entities and just refer to Liferay's own entities. Servicebuilder will generate JSON or SOAP WS if you let it. (what Slimen Belhajali mentioned)
As you specifically talk about the check for user identity, you might even want to think of a completely different solution and just look at single-sign-on (SSO) solutions. This way you'd sign in only once (to the SSO server) and automatically (implicitly) to your webapp as well as to Liferay. This works best if both access the same userstore, e.g. on LDAP.
I manage few spring based web applications. for example if my client is a flex application, with many modules/screens. Access to the screen or page or even a spring service is controlled by spring security based on the user role.
At certain time we may want to block access to that screen or service completely irrespective of the access granted by role. May be we want to take down a specific page/screen or a service for maintenance. and enable it after certain time. What is the best practice to achieve it. I do not want to restart the application.
I think of using some filter, so every request will pass through the filter and this filter will have the logic to check , if the current operation or view is allowed or disabled.
Is this the better way to handle it. or Is there any other solution.
What is the best practice.
Servlet filtler is a good choice if you want to block pages known by URL. This solution is simple and pretty straightforward.
Spring aspect will be better if you want to block services. Just wrap classes you would like to block and perform a check prior to calling it. Throw a specific exception that you can handle in the presentation layer.
We implemented a similar feature once in REST-based application. A global filter/aspect blocks all non-GET methods effectively switching an application to read-only mode.
You can always front your application with an apache httpd (or some other reverse-proxy web-front) and control access to individual URL-patterns there. That also gives you the added benefit that you can actually have a nice maitenance-page up while you take down the entire application.
There is a business problem that needs to be solved. The obvious solution is an enterprise web application - a locally hosted website that provides the desired functionality.
I want to build this web application, but build it such that -
Its more of a product than a one-time solution; such that it can be customized for different clients
It is possible to provide 'fixes' for this web application, so that bugs can be removed and enhancements added with minimum impact on operations
The web app should be capable of working with different databases and existing authentication systems
Is this even possible? Is it a common enough approach that there is a known way of going about this? Would it be better to use an application framework like Spring or try and keep dependencies on frameworks to minimal?
Also, any links or references to books that will guide me will be greatly appreciated.
Thanks in advance StackOverflow!
(I feel like I dont know all what I need to know before embarking on this project, please feel free to point out things I haven't and should consider)
Developing software, esp. for re-usability, requires analyzing which parts/functions are common between use cases and which aren't, drawing the line between re-usable (library) and customized/specialized code.
If you know what use cases you expect or want to support in the future this can be feasible.
If you don't, you should not start trying to generalize arbitrary functionality in the first place, because you cannot know what you will be needing in the future.
Java provides some good abstractions of various functionalities, like universal DB support via JDBC.
If you didn't already, have a look at application servers like JBoss or Glassfish. They provide plenty of basic functionality for web applications, support very loose coupling between components, and are highly configurable. To switch from one DBMS to another, for instance, it is enough to alter a single line of configuration (given the supported SQL is similar enough). Deploying applications or parts can often be done on the fly ("hot deployment") without even stopping the server.
Plus: There is a vast amout of supporting libraries and frameworks out there to help you standardize your application design.
I have been working for a while on a webapp that can be deployed in multiple locations: it is designed to be instantiated on many hosts. It's entirely possible to do this, but it is difficult. Writing the code so that it can work this way takes a great deal of care.
The key to doing it is to make all your dependencies on things explicit and all your configuration driven by properties that can be set during installation. Spring makes this quite a lot easier! In particular, the org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer class allows you to use the servlet context as a source of values that you can then inject into your beans (e.g., via #Value annotations). It's far harder to do all that yourself. Here's (a simplified version of) what I use:
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="contextOverride" value="true" />
<property name="location" value="/WEB-INF/default.properties" />
</bean>
This merges the servlet context's properties on top of the ones you provide as defaults inside your webapp (definitely a good practice if most things aren't going to need to be modified most of the time) and then uses them to define properties. I then apply a configuration property (e.g., foo.bar) to a bean property using a placeholder, like this:
#Value("${foo.bar}")
public void setFoobar(String foobar) { ... }
Things to configure that way include the database configuration, absolute locations of files holding things that can't be packaged inside the webapp, etc. You'll have to use your skill and knowledge of the application domain to work out what things need to be listed.
Other key principles are to keep as much as possible inside the webapp (so reducing the opportunity for the deployer to mess it up), to be very careful about documenting everything, and to try it with multiple servlet containers. Remember, the person deploying your webapp does not have access to the contents of your thoughts: you have to write it down and tell them exactly what to do. (Too many instructions are at the level of “click this, click that, magic happens” but those are poor instructions since the exact method will vary over time: saying why will help far more because its more portable.)
We are currently developing a product that can be deployed internally for multiple clients and also as a public portal solution. Here is our experience.
As others have pointed out, there are different factors to keep in mind.
Security
Security that is associated with your product, and how you would manage the product functional requirements to external security roles.
Security, authentication and authorization should not be as part of the base product. Once authorized the roles need to be mapped to product roles for achieving said functionality.
Images and logos, that require customization.
Internationalization.
For working with multiple databases, assuming a product has typically two different views, persistence and querying. Our experience was to use hibernate to support multiple databases, but theoretically we have used only two databases in the past. db2 and mysql.
Testing for multiple databases for every release of your product is a pain. Your test cases goes 3 fold or atleast once in a while to support multiple databases.
Using custom databases and functions are a big no, you can use some general functions but custom database specific functions in your query are going to be a pain and have to be very diligent to avoid them.
Supported browsers in your product.
Licenses of the third party jars may not be compatible / acceptable to all institutions so you have to watch out for that carefully.
As much as possible, enable properties or configuration to customize all variables.
Caching strategy and properties initialization strategies.
A framework helps the team to keep on the same page, rather than an internal framework. There are many advantages to use a well established framework like Spring for performance and other consideration.
Cheers!
I want to give access to some of the resources in my web application to the logged-in users only. I implemented the authentication without using any j_security_check as I find it very rigid and non-transparent. I want to know if there is any clean way of restricting access to the web resources without being dependent on the web.xml(security-constraint and web-resource-collection elements).
Also, I do not want to use any bloated frameworks such as Spring or such.
You can define a Filter, map it to /* and let it handle the restricted resources. List them in your own configuration file, and check if a user is logged when accessing one of these resources. If not - redirect to a login page; if yes - continue (chain.doFilter(..))
Using the security model controlled by web.xml is the primary way of controlling authorisation. I think you're in danger of re-inventing the wheel here. The standard facilities are really quite powerful, I'd agree that there's a learning curve but resources such as these help.
For dynamic resources you are free to implement your own authorisation model, and for complex authorisation that is what folks do, this article may help.