I am developing an application in which i am using angularjs at client side and java,spring at server side,all communication is in the form of JSON.
The problem i am getting is about security.
I have multiple roles, user can have and based on these roles,tabs on UI are visible or not.
If i use JSP then it is easy to use taglib for this problem because jsp is compiled at server and returned html will not have html section for hidden tabs and there is no way by which end-user can see these tabs or their URL part.
But how to solve this problem in angular based application because whatever code i write in angular file,user can change it by firebug etc. and can see the tabs and their URLs.
example : i have following in my html :
Users
I want to hide this thing completely if user is not having required role.
One solution can be writing some directive but user can edit the script of this directive and can see this thing in html.
You need to do 2 things :
Implements an angular Service, giving your client side the authorization (obtained by REST)
Then, on the server side :
you need to protect ALL RESOURCES (html, angular controllers, angular services, rest resources) depending on the user's rights.
May you can protect only Rest Resources if Client side's ones are not critical (I don't mind if my user get my html).
This way, the user won't see the tabs he is not supposed to, but more important, he can't bypass your security in order to show it.
By protecting HTML, I mean that for the tab XX I use ng-include="'tabXX.html'", and I protect this html with Spring Security the same way I protect RestResources.
Related
I know what I am asking is somehow weird. There is a web application (which we don't have access to its source code), and we want to expose a few of its features as web services.
I was thinking to use something like Selenium WebDriver, so I simulate web clicks on the application according to the web service request.
I want to know whether this is a better solution or pattern to do this.
I shall mention that the application is written using Java, Spring MVC (it is not SPA) and Spring Security. And there is a CAS server providing SSO.
There are multiple ways to implement it. In my opinion Selenium/PhantomJS is not the best option as if the web is properly designed, you can interact with it only using the provided HTML or even some API rather than needing all the CSS, and execute the javascript async requests. As your page is not SPA it's quite likely that an "API" already exists in form of GET/POST requests and you might be lucky enough that there's no CSRF protection.
First of all, you need to solve the authentication against the CAS. There are multiple types of authentication in oAuth, but you should get an API token that enables you access to the application. This token should be added in form of HTTP Header or Cookie in every single request. Ideally this token shouldn't expire, otherwise you'll need to implement a re-authentication logic in your app.
Once the authentication part is resolved, you'll need quite a lot of patience, open the target website with the web inspector of your preferred web browser and go to the Network panel and execute the actions that you want to run programmatically. There you'll find your request with all the headers and content and the response.
That's what you need to code. There are plenty of libraries to achieve that in Java. You can have a look at Jsop if you need to parse HTML, but to run plain GET/POST requests, go for RestTemplate (in Spring) or JAX-RS/Jersey 2 Client.
You might consider implementing a cache layer to increase performance if the result of the query is maintained over the time, or you can assume that in, let's say 5 minutes, the response will be the same to the same query.
You can create your app in your favourite language/framework. I'd recommend to start with SpringBoot + MVC + DevTools. That'd contain all you need + Jsoup if you need to parse some HTML. Later on you can add the cache provider if needed.
We do something similar to access web banking on behalf of a user, scrape his account data and obtain a credit score. In most cases, we have managed to reverse-engineer mobile apps and sniff traffic to use undocumented APIs. In others, we have to fall back to web scraping.
You can have two other types of applications to scrape:
Data is essentially the same for any user, like product listings in Amazon
Data is specific to each user, like in a banking app.
In the firs case, you could have your scraper running and populating a local database and use your local data to provide the web service. In the later case, you cannot do that and you need to scrape the site on user's request.
I understand from your explanation that you are in this later case.
When web scraping you can find really difficult web apps:
Some may require you to send data from previous requests to the next
Others render most data on the client with JavaScript
If any of these two is your case, Selenium will make your implementation easier though not performant.
Implementing the first without selenium will require you to do lots of trial an error to get the thing working because you will be simulating the requests and you will need to know what data is expected from the client. Whereas if you use selenium you will be executing the same interactions that you do with the browser and hence sending the expected data.
Implementing the second case requires your scraper to support JavaScript. AFAIK best support is provided by selenium. HtmlUnit claims to provide fair support, and I think JSoup provides no support to JavaScript.
Finally, if your solution takes too much time you can mitigate the problem providing your web service with a notification mechanism, similar to Webhooks or Resthooks:
A client of your web service would make a request for data providing a URI they would like to get notified when the results are ready.
Your service would respond immediatly with an id of the request and start scraping the necessary info in the background.
If you use skinny payload model, when the scraping is done, you store the response in your data store with an id identifying the original request. This response will be exposed as a resource.
You would execute an HTTPPOST on the URI provided by the client. In the body of the request you would add the URI of the response resource.
The client can now GET the response resource and because the request and response have the same id, the client can correlate both.
Selenium isn't a best way to consume webservices. Selenium is preferably an automation tool largely used for testing the applications.
Assuming the services are already developed, the first thing we need to do is authenticate user request.
This can be done by adding a HttpHeader with key as "Authorization" and value as "Basic "+ Base64Encode(username+":"+password)
If the user is valid (Users login credentials match with credentials in server) then generate a unique token, store the token in server by mapping with the user Id and
set the same token in the response header or create a cookie containing token.
By doing this we can avoid validating credentials for the following requests form the same user by just looking for the token in the response header or cookie.
If the services are designed to chcek login every time the "Authorization" header needs to be set in request every time when the request is made.
I think it is a lot of overhead using a webdriver but it depends on what you really want to achieve. With the info you provided I would rather go with a restTemplate implementation sending the appropriate http messages to the existing webapp, wrap it with a nice #service layer and build your web service (rest or soap) on top of it.
The authentication is a matter of configuration, you can pack this in a microservice with #EnableOAuth2Sso and your restTemplate bean, thanks to spring boot, will handle the underlining auth part for you.
May be overkill..... But RPA? http://windowsitpro.com/scripting/review-automation-anywhere-enterprise
I am having a html page, which takes in the username and password and takes it to the servlet for authenticating. If authenticated, it gets a link to go to another html page, which accepts input for placing a order, this inputs are finally passed to a servlet, which makes the data persistent by storing it in the database,
By far, i can make a html page for username and password and a servlet for authenticating. even the link for going to another html page, which accepts the input of the order details also works, after that, the servlet does not work.
Using Glasfish Server and netbeans for development.
check Servlet Filter : they are invoked before/after a servlet, and are used to handle authentication, caching, etc
I'm trying to do a single page application using servlets and jsp pages.
For the moment I have the first page, which is simple to do: a servlet that forwards to the corresponding jsp.
How should the implementation look when navigating to the second page?
I guess it should be an ajax call, the servlet would populate the necessary data, but how to display the second page jsp?
JSP is a server side ui technology. A Servlet listens to specific urls and redirects to JSPs pages. The JSP is compiled to a class (another servlet in fact), invoked (data will be added and inline scripts will run) and the output, whith is HTML, is send to the client (browser). To get to a different page its neccessary to query the server (servlet) for another url, resulting in another html page.
To create an SPA you need a client side technology like JavaScript. Your query the server for a single html page. The page, made of HTML and JavaScript, for example, (could even be the output of a single JSP, dont get confused) is send to the client (browser) and the JS is run. This is nomaly backed up by a framework like AngularJS, EmberJS or Backbone. Once the page is set up, the links within the page are anchors (http://example.com/#/mySecondPage), so clicking them will invoke the framework again (Ajax, querying the server for new data), but will stay on the same page. Some contents of the page might then be replaced by new content.
If it is a true SPA then you would just have a single JSP and handle all your functionality (after your initial page load) using Ajax.
Have you looked at using a client-side framework such as Angular to help you with this?
Depending on how rich your SPA is, you could either use the same servlet or multiple servlets to serve each page.
Unless you are doing this for a course or tutorial and have some constraints on how to achieve it, you will very probably save yourself a lot of time if you couple something like Angular with a server-side framework like Spring instead of coding servlets. As a suggestion have a look at Spring with Angular.
In SPA the browser only loads the document once (or a few, once per sub-application), and further communication to the server is done usually via AJAX or Websockets.
I recommend you to model your application as a thin server architecture, that is, a client application running in the browser (HTML, CSS, Javascript) consuming a web service API provided by the server.
The following are some points worth knowing;
Client-side:
Only presentation logic
Represent state by URL hash. This enables bookmarking, hyperlinking and browsing history. Your client app should listen to changes in the URL hash and act in consequence. This technique is called "routing" and it is implemented by all Javascript frameworks.
Client application is packaged server-side such it can be downloaded in a single request (in .html, .jsp, servlet, .jsp + multiple .jspf, ...)
Consumes services provided by the server via AJAX or Websockets
Server:
Offers client application to download
Provides a clean, stateless API to be consumed by the client application, better returning JSON (data) than HTML (presentation logic) (Why is it a bad practice to return generated HTML instead of JSON? Or is it?)
Use a REST or JSON-RPC frameworks to create the API. There is a lot of debate on what to choose (see here or here). In my opinion the only advantage of REST over RPC is that since REST has become a "de facto" standard its interoperability is higher, so my recommendation for SPA applications is using JSON-RPC, because your code is the only client of the API.
There are lots of alternatives for both client and server frameworks.
Javascript: AngularJS, EmberJS or Backbone,...
REST: Spring, Jersey, Restlet,..
JSON-RPC: https://en.wikipedia.org/wiki/JSON-RPC#Implementations
Regarding JSON-RPC, you might want to take a look to Brutusin-RPC, a JEE microframework I have created :)
If you are using an Ajax request, then you need to tell the browser that redirect to the second page. Example:
response.sendRedirect("second_page.jsp");
In your servlet, you need to differentiate a request to the first page, from a request that need to be redirected to the second page. You can use parameters, or session values, for example.
if (request.getParameter("page2") != null) {
response.sendRedirect("second_page.jsp");
} else {
.... // include here the normal logic of your Servlet for page 1
}
Then, you can invoke your servlet with or wihout the parameter page2, to go to page 1 (without parameter), or page 2 (with parameter).
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
I have a web PHP web application that has a link to a java web application. The php application has a login page, and a link to the the java application, but not every user has permission to access the java web application. What I was trying to do is send user credentials from the php application to the java application, and then the java application checks the credentials and if correct logs in the user. I was thinking of using http headers to do this.
So my question is what is how to send user credentials from a PHP application to a java application?
If it helps I am using a Java web framework called Vaadin.
Do a normal POST request from the PHP application to the java application. This can be done as simply as having a normal HTML form in the PHP application, set the form's method to "POST" and action to the java application's URL. If you want to catch HTTP parameters in a Vaadin application, you can do it by using request handlers (https://vaadin.com/book/vaadin7/-/page/advanced.requesthandler.html).
Then a few words of advice or something to at least consider. If your login page is in the PHP application and your "admin" application is the Vaadin application, then I discourage you from doing the credential checking in the Vaadin application. This is because when you enter the Vaadin application, a new application instance is created. This means that your UI will be initialized and whatever else you do in the UI's init method. What you probably want to do, is to hinder the user from entering the Vaadin application unless she is logged in - which means that you need to do the credential checking somewhere else - for example, have a separate servlet whose only responsibility is to log in the user. If login is granted, then give access to the Vaadin application, if access is denied, forward the user to the PHP login screen. The next question is, how do you hinder the user from accessing the Vaadin application until she is logged in? Typically, this is done using servlet filters.
I highly encourage you to use a 3rd party framework for doing the authentication and authorization. Take a look at http://shiro.apache.org/, it's easy to install and seems to work nicely together with Vaadin. All you need to do is to configure it and implement a login screen, the framework will take care of the rest.
If I understood your question, you want to be able to provide an "auto-login-link" to some specific users that are logged in to the PHP application. This link should automatically login the user to the java application, right?
Without knowing any details about this case, like are both apps running on the same domain or do they use the same database (same user credentials in both apps), etc., I would propose the following solution:
Create an action (link) on the java application, which receives the necessary parameters (as GET) needed for creating the session (probably userId is sufficient), timestamp and a signature of all parameters. For example:
http://javaapp.example.com/autologin?userId=123&timeStamp=123456789&sign=hj23kh4j234jk324h
Where the signature is calculated with some strong encryption algorithm. Then you verify that the signature is correct at the receiving end (java app). If it is correct, you create the session. Signature calculation could be something like:
$signature = sha1($userId . $timeStamp . 'some salt' . $sharedSecretBetweenBothApps);
With the timeStamp you are able to check that an old link is not used. For example not allow older than 15 min old links and store used links in the java app to make sure they are never re-used. You do not have to keep history of links older than the expiration time.
Another idea, as discussed in the comments, is creating an API on the java side, which is able to provide a one-time link.
The sha1 algorithm is probably not strong enough, but shows the idea and is simple to implement.
Does this answer your question?