Background: Our current technology architecture includes Tomcat Servlets that do backend activities and Codeigniter PHP which handles the presentation layer. So when a particular page is loaded, the Codeigniter View invokes the Controller which constructs the servlet URL with necessary input parameters and invokes the URL and gets the response and passes it back to the View so that the page is rendered.
Issue: User information and login credentials are stored in database and is validated by PHP front end. There is no authentication for the Tomcat servlets and in cases where we need user information in the backend, the user id is passed as a parameter to the backend.
Currently Tomcat and PHP resides on the same server and we have used firewall port based restrictions to ensure that servlets can be invoked only from within the server to secure the servlets.
Help required : We are looking to implement token based authentication and authorization mechanism for the servlets. If we can get some sort of existing library that we can easily plug-in to our servlets, that would be ideal. Otherwise please guide what would be the best solution to implement without too much code changes but would effectively secure the backend servlets.
Cássio Mazzochi Molin have a nice articel about the topic : Token-based authentication with JAX-RS 2.0
Related
We have an existing legacy web application(Servlet+jsp+spring+hibernate) and we are going to develop some new features of the application using a new stack (angularjs+Spring mvc). Currently suggested approach is to register a new servlet and develop the new features in the same codebase, so the authenticated users will have access to the new functionality we develop in the system. Is there a better way of doing this as a two different web applications (without SSO) ? Can two web applications be secured under the same form based authentication settings ?
I think architecture and security usability is very important before dive into something.
If both apps use same login, then I assume the newer application is more likely a service oriented application. Ex: RESTful
Authorization may be an issue. Ex: Legacy app is used by user set A, new one is used by both user set A and B.
Otherwise you can use a shared database for example MongoDB to store your login info i.e token.
When you log in, return that token and use for the other service via angular client. When you log out remove any token for that user session. You may also need to concern about token expiration.
However you have to refactor your legacy system in someway to use a token. If it is not possible, you can use session sharing which is handled by the the container if the the both apps are running under same container. Ex: Tomcat. But now it may very hard to integrate with a native mobile app if you are hoping to do so.
Sharing session data between contexts in Tomcat
From the point of Spring security and angularjs, authenticating via form is just an http POST with content type being application/x-www-form-urlencoded. One difference is the response to a non authenticated request, for one response should be a http redirect (jsp, to a login page), one with an unauthorized code (for angularjs). That could be handled with a custom AuthenticationFailureHandler or on the client side. A similar difference may occur for the successful login redirection.
I have been following the example in this tutorial: https://spring.io/blog/2015/01/28/the-api-gateway-pattern-angular-js-and-spring-security-part-iv
In brief:
I have a server called UI that has some html and angular js.
I have a server called resource that has a RestController who is serving the content from a DB. All the calls must be authenticated.
The UI server has a login page which works with spring http basic login and creates a spring session that is stored in a Redis server and it is shared to the resource server. When i have some dummy users in memory authentication everything works fine.
The question is:
I want my UI server to be able to perform a login with real users, that exist in the DB. The UI server should not have any DB related code (not knowing its existence) but it should call a REST service in the resource server. The only way i was thinking (but is sounds wrong to me) is to implement a userDetailsService bean in the UI and the loadUserByUsername method should call a rest service from the resource server (e.g. /getUser). The rest service should return all the user details including credentials and roles for the given username. However, to my understanding, this service cannot be secured (for the call to be successful) which compromises the entire security.
I am open to all suggestions and recommendations. Bare in mind this is my first attempt to work with Spring.
Thank you in advance,
Nicolas
In case that someone is interested how i tackled this..
I decided to do the prudent thing and study spring security.. :)
My answer is to use a custom AuthenicationProvider in my UI server, which will call an unprotected rest login service in the resource server, which in turn validate the user against the DB.
If the response is successful (e.g. a user object could be returned with username, password, roles) then i will create a UsernamePasswordAuthenticationToken object out of it and return it.
If the response is NOT successful (e.g. return object was null or an exception was thrown) then i will either return null or throw an AuthenticationException, it depends on how Spring behaves... I haven't reached that part of studying yet..
http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#tech-intro-authentication
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
Spring Security is a framework that focuses on providing both authentication and authorization to Java applications. Like all Spring projects, the real power of Spring Security is found in how easily it can be extended to meet custom requirements
Features
Comprehensive and extensible support for both Authentication and Authorization
Protection against attacks like session fixation, clickjacking, cross site request forgery, etc
Servlet API integration
Optional integration with Spring Web MVC
I'm pretty new to Angular and jsp and I have a question about general architecture of a single-page system.
I understand that jsp mvc has it's own security features that some of course related to conditionally delivering static/dynamic pages to the clients.
How can that feature work with Angular? Obviously in a single page application, working with partials, the server does not need to pass pages to the client.
My specific question is about the login page. Do I need to separate my login html from my main 'single-page' index.html with all my routes?
Will I have a 'login.jsp' file which is a stand-alone file handled by jsp and only after login routing to the single-page part of the application?
Thanks!!!
Regarding the login part:
My recommendation is that as an application developer you should not be thinking in how to implement your login page. This would bind your application to a specific authentication mechanism, and its a sign of getting into troubles (implementing the whole app security by your own)
It is preferable that this binding is performed in a pluggable (declarative) way, like it is done in JEE by the container or in Spring security by a dedicated framework.
So answering your question: you should no have a login.jsp at all, this page would be automatically generated once you have properly configured your application security with a 'login form' authentication mechanism. (Both JEE and Spring provide also mechanisms for customizing this pages).
The framework/container would intercept the request to your web app, identify if the user is authenticated, redirect to the login page and finally redirect to the original url, if authentication succeeds.
Cheers,
Nacho
We are planning on developing a layer of REST services to expose services hosted on a legacy system. These services will be used by a classic web application and native mobile phone applications.
This legacy system is secured in such a way that an initial username + password authentication is required (a process that can take 5 to 10 seconds). After the initial authentication, a time-constrained token is returned. This token must then be included in all further requests or else requests will be rejected.
Due to a security requirement, the legacy security token cannot be returned outside of the REST service layer. This means that the REST service layer needs to keep this token in some form of user session, or else the expensive username + password authentication process would need to be repeated for every call to the legacy system.
The REST service layer will be implemented using a Java 6 + Spring 3 + Spring Security 3 stack. At first sight, it looks like this setup will run fine: Spring-based REST services will be secured using a rather standard Spring Security configuration, the legacy security token will be stored in the user's HTTP session and every call will retrieve this token using the user's session and send it to the legacy system.
But there lies the question: how will REST clients send the necessary data so that the user's HTTP session is retrieved properly? This is normally done transparently by the web browser using the JSESSIONID cookie, but no browser is involved in this process. Sure, REST clients could add cookie management to their code, but is this an easy task for all Spring RestTemplate, iPhone, BlackBerry and Android clients?
The alternative would be to bypass the HTTP session at the REST service layer and use some other form of user session, maybe using a database, that would be identified using some key that would be sent by REST clients through a HTTP header or simple request query. The question then becomes, how can Spring Security be configured to use this alternative session mechanism instead of the standard Servlet HttpSession?
Surely I am not the first dealing with this situation. What am I missing?
Thanks!
There's nothing magical about cookies. They're just strings in HTTP headers. Any decent client API can handle them, although many require explicit configuration to enable cookie processing.
An alternative to using cookies is to put the JSESSIONID into the URL. I don't know anything about spring-security, but it seems that that's actually the default for at least some types of URL requests, unless disable-url-rewriting is explicitly set to true . This can be considered a security weakness, though.
Unfortunately authentication is highly problematic -- a bit of a blind spot in terms of web standards and browser implementations. You are right that cookies are not considered "RESTful" but purists, but even on fully-featured browsers avoiding takes quite a bit of hackery, as described in this article: Rest based authentication.
Unfortunately I haven't done any mobile development, so I can't suggest what the best compromise is. You might want to start by checking what authentication models each of your targetted platforms does support. In particular, two main options are:
HTTP authentication (ideally "digest", not "basic")
Cookies
One possibility would be to provide both options. Obviously not ideal from a technical or security point of view, but could have merits in terms of usability.
I'm using gwt on my glassfish server, and I'm attempting to make some of my RPC calls authenticated via cookies. Is this possible? Are there any examples out there of how to code it?
Depending only on the cookie for authentication will make your website/services vulnerable to Cross-Site Request Forging/XSRF/CSRF attacks - read more on that in Security for GWT Applications.
The best way would be to double check the value you get from the cookie and with the one that's been transported to the server by some other means - as part of the request (header, a custom field, etc).
Other than that, there are many tutorials covering the subject - just search for Java (servlet) authentication - it doesn't have to be GWT-specific. The Google Web Toolkit Group also has many threads about the subject.
I assume that you use GWT's RPC servlet for handling requests made by the client.
One option that comes to my mind is to write and configure a ServletFilter which can examine the cookie, before the request reaches GWT's servlet.
You might rethink using cookies as it is a potencial security hole.
Why not put your communication to HTTPS?
Can you not just use the standard 'session' scope, i.e.
request.getSession()
A pattern I use in GWT apps is to have a separate 'old fashioned' login form which sets up the session. The GWT app's host page is then displayed after they have successfully logged in.
If the necessary values aren't in the session, then the user isn't logged in. Your service should return an exception, maybe, which instructs the GWT app to redirect to the login page, or display an error.