Servlet Parameter Encryption - java

Still learning JSP Web Applications here.
I have been doing this for a while in my web application but I would like to know a more secured solution.
Imagine a Table that displays certain Book Information. When user clicks one of the rows in the table,
I basically send the BookID together with the url.
Example URL. http://locathost:8080/myapp/editbook.htm?bookID=3
in my servlet.
String strBookID = request.getParameter("bookID");
I think this is a little weak, is there a way where I could provide a more secure way other than this.
Its quite easier for hacker to edit the URL if I send the BookID together with the URL.
Can you share me some link on how to do this in both the Client Side and Server Side?
Thanks

I think this is a little weak, is there a way where I could provide a more secure way other than this.
You have to define "secure" on the basis of your application. The requirements are totally different for a public website selling books v/s a private library hosting confidential volumes v/s anything other application in between.
At a minimum, you should do the following -
Verify that bookID is in fact an Integer and is within an expected range.
Ensure that you bind bookid in a parameterized SQL Query - this is to prevent SQL Injection.
Show a 'Book not found' page if the book cannot be found
For a public website, the above is enough. You actually want people to discover your books, so if someone modifies the bookID, you shouldn't care.
For a secure library, you have to do a lot more.
Ensure that the URL is protected in web.xml, so only authenticated and authorized users can get to the URL
Verify the current user has access to the bookID. You can store the list of books available to a user in the session object.
If the user does not have access, return a 403 error page.
There are several other strategies to protect URLs; some use tokens to ensure the URL hasn't been manipulated. Others don't send bookID to the client, and instead rely on number {1 through n} where only the server knows that 1 corresponds to Book A and so on. But the idea is to ensure that a user doesn't get access to a book he doesn't have permissions to.
If you are using Spring, I'd highly recommend Spring Security. Otherwise look into JAAS.

You have to suppose that any user can send anything to you. The solution isn't avoiding users to send data in URL, it's to control that they can in fact do the following operation.
You need authentication and authorizations.
How to use authentication with your web.xml
Defining Security Requirements for Web Applications

Related

Is there a way to access session data that was set in the openid connect process?

When I try to access Liferay Portal session data it seems as it doesn't contain data stored by internal Liferay Portal processes. Is it possible to access the token that was stored in the OpenId-Connect Login process?
Basically, I was tasked with finding Software, that can make implementing a Portal, which displays functionality offered by API-Endpoints of multiple different internal Platforms easier. Currently, I'm looking at Liferay Portal 7.2. For the Login, I've used the OpenId-Connect implementation of Liferay Portal since authentication is handled by an internal Login server. The access token returned at the end of the OpenID-connect login process is an API-Token which I then want to use to access various API-Endpoints.
Currently I get the Session like this
HttpSession httpSession = PortalUtil.getHttpServletRequest(actionRequest).getSession();
After looking at the OpenId-Connect implementation in
com.liferay.portal.security.sso.openid.connect.internal.OpenIdConnectServiceHandlerImpl
I then tried to get the Session Object like this.
Object openIdConnectSessionObject = httpSession.getAttribute("OPEN_ID_CONNECT_SESSION");
But at this point, openIdConnectSessionObject is always null. I have read that different scopes have different sessions, but is there a way to access this data or is Liferay Portal maybe not really fit for what I'm trying to do.
There's one detail worth noting:
PortalUtil.getHttpServletRequest(actionRequest) will give you access to an artificial PortletRequest object that adheres to the HttpServletRequest interface, in case you need that for some API that expects requests from the servlet, not the portal, world.
A PortletRequest contains only parameters (and session information) directed to a particular portlet, and nothing else.
If you're interested in the actual underlying HttpServletRequest, you'll need PortalUtil.getOriginalServletRequest, which takes an HttpServletRequest as input. And you'll get that the way you've already explored. In the end, you'll have
session = PortalUtil.getOriginalServletRequest(
PortalUtil.getHttpServletRequest(actionRequest)).getSession();
to get the actual server's session.
I've not checked if that is useful, or even an advisable solution to the problem you state, but it might bring you further along solving your problem.

REST GET Design Issue

I am currently new to RESTful Architecture and using Jersey to practice. i am facing difficulty in implementing GET operation.following REST naming/URL convention for getting a particular customer from the server would be
GET http://www.example.com/customers/33245
However while designing client side how would the client know that specific id belong that specific customer as it would be in the database linked with the server and hidden from client. One implementation i think of is to extract all the information regarding all the customers from the database and store in the client but i believe it kills the whole purpose. what should be the optimum way for searching for a specific customer.
Such an URL is used for getting a customer that you already know. Not for searching customers.
For searching customers, you would typically use an URL like
http://www.example.com/customers?name=Doe&firstname=John
This would list all the customers named John Doe, and the list would contain, for every customer, the ID of the found customer. The client would then use this ID to invoke the URL in your question and get detailed information about this customer.
You can of course use any query criteria you want, or allow accessing customers by other means.
If you think about it, that's exactly how web searchingworks. You don't know the URL of a page, you search for this page by keywords on Google, which returns a list of results containing the title, description and URL of thepage, then you use the URL to actually access the page.

Restrict access to fields if not authorized in REST-ful API

Let say you have a User resource. It has many fields. However, not all fields should be allowed to updated by a regular user, but admins should be allowed. Are there any common solutions to this?
E.g. enabled should only be allowed to be updated by using a PUT request if the authorized user is an admin. How should I do this?
Have you heard of spring-security authorization? They have a way of hiding the fields based on the user roles. If your app is large, it makes sense to integrate this.
Lookup for methodlevel security
Domain object security (ACL)
Good article about entity filtering here
http://blog.dejavu.sk/2014/02/04/filtering-jax-rs-entities-with-standard-security-annotations/

How to map additional LDAP attributes to the Principal object in Glassfish?

I have configured a LDAP realm in Glassfish, and authentication works just fine.
Now I am wondering how could I match the Principal.getName() return to a certain attribute of my LDAP user object. I thought it would use something such as "givenName" by default, but it returns the username used for authentication.
I don't mind making an extra trip to the LDAP server to obtain the additional information, but instead of keeping the LDAP connection attributes in my application, I'd like to inject the security realm (if such a thing is possible) and use its own connection.
So, in short, the questions are:
1) Can I map additional attributes to the Principal returned by the realm?
2) If number one is not possible, then how could I reuse the realm's information in order to connect to the LDAP server and obtain the data I need?
Thanks in advance for any help or suggestions.
The JAAS Subject often contains many principals, each one representing a different attribute.
For Java EE one, and only one, of these Principals is selected for the one that is returned when you call HttpServletRequest#getUserPrincipal and similar methods. The other Principals are for the Java EE API just lost.
You can determine which of those Principals to select by writing a JASPIC authentication module if the login happens via HTTP or SOAP.
You can preserve the entire Subject by putting it into the HTTP session from within the JASPIC authentication module. Other code can pick it up from there.
Edited: I was under the impression that the following used to work, at least with GlassFish 4.0. Unfortunately, that doesn't (any longer) seem to be the case. A workaround can be found in the comments of this issue.
Not really a solution per se; just a little detail I kept overlooking for a while, and which was quite a relief for me to have now become aware of. So --skipping the boring specifics-- I realized that a CallerPrincipalCallback(Subject s, Principal p) constructor is additionally available, which, when supplied with my custom Principal, causes the server to actually retain it, instead of wrapping it in or transforming it into an internal GlassFish implementation instance, as I previously thought it would. From "userspace" I was then able to access my "enriched" (more Subject- than Principal-like, to be honest) version the usual way (e.g. ExternalContext#getUserPrincipal, etc.), cast it and enjoy the convenience of not having to care about deriving custom Principals from generic ones in each application from now on :) .
Well, I could not extend the Principal attribute mapping without using a custom LoginModule; so, instead I opted to the solution described here: http://docs.oracle.com/cd/E19798-01/821-1751/abllk/index.html
What I do is, upon authentication, use the injected LDAP context to go back to the LDAP server and obtain the attributes I want. The downsides are obvious: two trips to the server instead of a single one, and the extra code to probe attributes and tie them to the Principal (or another POJO) in some way.

Managing state in RESTful based application

We are evaluating the technology to be used for a web based application and some suggestions are to go with RESTful based services approach.
Tech Stack
1) Spring
2) Apache CXF ( JAX-RS)
My questions are
1) How state is managed between requests. For example, a user has been authenticated and now he is making a series of requests lets say going through a paginated report. I would imagine the URL for this will be like
domain.com/reports/customreport/page/1
domain.com/reports/customreport/page/2
etc...
a) Where is the user information & request parameters are stored so that it can be shared between requests.
b) Lets say the result is being streamed, where is Rowset is stored?
Is there a complete sample application something similar to Petclinic that can provide the best practices for such an application.
If you are doing RESTful strictly / properly, then user authentication is done in each request and there is no concept of a session. Each request contains enough context information (in the URL and/or request parameters) to allow it to work independent of a session.
1) How state is managed between requests.
It must be managed by the client.
a) Where is the user information & request parameters are stored so that it can be shared between requests.
User authentication information is stored by the client and provided to the server with each request. The server will recalculate any derived information about the user on each request. Any request parameters that would normally be stored in a server-side "session" must be passed afresh with each request.
b) Lets say the result is being streamed, where is Rowset is stored?
In the first instant, nowhere. The query is reissued each time with a parameter saying where to skip to. If performance was an issue, you could
read-ahead a few pages of the result set and store them in a server-side cache, or
tune the database query caching for the query.
1) The user information is not stored anywhere, the user has to send his credentials (or whatever authentication method you're using) on every single request.
2) Streaming doesn't make much sense in a RESTful API, if you would like to do streaming I'd greatly advice you to look for something like WebSockets (in Java you can easily do this with Jetty)
If you said streaming but you meant paginated results, same as 1, there is no state kept, the client has to send a new request with all the information and the server has to query the database (or go to a cache, or do anything needed) and return the result to the customer.
You should also read more about REST, as your question is quite vague, one good start is the Restful Web Services book or, if you feel adventurous, you can try Roy Fielding dissertation that defined what we call REST today.

Categories