jsp : safe selection menu - java

I'm new to the use of jsp's, servlets, beans etc ... .
Maybe a strange question, but what is the safest way to make a selection menu in a jsp, to make sure you can't access it directly.
At this moment I have a login system and depending of the "kind" of user I retrieve from the db I send them to a specific jsp depending on the "permissions" they have. On this page they will get a selection of the possibilities they can do.
but if I use something like:
next option
it would be easy to just access these next pages from the outside (not much use for the login system then).
I can use a bean I retrieve from the previous page that I check if it's null (this would be so if you get directly to this page) or something like that.
Any suggestions would be welcome. thx

You can use a Servlet Filter to validate if the user has logged in the system and to verify if the user has the rights to access to this page. An example would be as stated in StackOverflow Servlet-Filters wiki. Posting the relevant code:
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
//session.getAttribute("user") contains the user info in session
if (session == null || session.getAttribute("user") == null) {
// No logged-in user found, so redirect to login page.
response.sendRedirect(request.getContextPath() + "/login");
} else {
// Logged-in user found, so just continue request.
chain.doFilter(req, res);
}
}

Related

Java JSP Filtering on Query String

I have a webpage I am currently building for an internal work tool. It is a sample website that allows a user to login and then execute query from the database. I just implemented a filter to re-direct not-logged in users to the login page. The doFilter function looks like this
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("user") == null) {
// No logged-in user found, so redirect to login page.
response.sendRedirect(request.getContextPath() + "/Login.jsp");
} else {
// Logged-in user found, so just continue request.
chain.doFilter(req, res);
}
}
In my web.xml I have
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>Servlets.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/Home.jsp</url-pattern>
</filter-mapping>
If I access Home.jsp directly it will re-direct to the Login Page. However, once logged in, the user is moved to the Home.jsp page which allows the user to execute a query against the database. The home URL will look like
http://localhost:8084/LiveTrades/Home.jsp
But once they provide input, it will move to a new page displaying the results with url string like
http://localhost:8084/LiveTrades/Request?BIC=cat (assuming the user entered 'cat' for the input 'BIC' field).
If a user inputs this above url directly when not logged not, it will process fine, when it shouldnt. I know this is because my filter is only being invoked from the Home.jsp page. How can I get around this to prevent pages with Request* to be filtered?
Would it be easier to have another jsp page, say Results.jsp, and have the Servlet that processes the information from the database pass the data on to Results.jsp? Then I can simply add Results.jsp to the web.xml.
I managed to solve this problem by re-structuring my webpage. The results are now displayed via a JSP page, the data is passed to the JSP page from a Servlet. Now in my filter I simply add the Result JSP page and problem solved.

Servlet authentication using sessions and cookies

I need to implement simple servlet user authentication (in Java Dynamic Web Project) but there are things that confuse me quite a bit.
Firstly, the servlet for some reason creates the cookie JSESSIONID although I never ask it to. And moreover, I cannot change its value, if I do request.addCookie(new Cookie("JSESSIONID", session.getId())), it makes something like this:
Cookie: JSESSIONID=6B5B441038414B4381EDB7470018F90E; JSESSIONID=7890D45DF445635C49BDEB3CADA8AD99; .......
so, it duplicates the cookie.
Secondly, I'm not sure where to compare cookie and session's id, and where and how to create session correctly (i.e. request.getSession(true? / false? / nothing?);)
I've read some documentation but still need help.
I have the servlet HomeServlet which shoud redirect user to authentication page if the user is not authenticated.
Here's how I do that (HomeServlet.java):
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(request.getSession().getAttribute("user") != null) {
request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
} else {
response.sendRedirect("authentication");
}
}
And I also have AuthServlet which serves jsp page with authentication forms and validates users.
AuthServlet.java:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("ACTION");
if ("login".equals(action)) {
String[] result = doSomeValidations();
if (result.size() > 0) { // show validation errors
request.setAttribute("errorLoginMessage", result);
request.setAttribute("email", email);
doGet(request, response);
} else { // authenticate user
request.getSession().setAttribute("user", userObject);
request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
}
} else if ("signup".equals(action)) {
// ...........................
} else {
doGet(request, response);
}
}
So, could you help me with understanding that? How do I implement user authentication and keep the user logged in throughout the session?
Firstly, the servlet for some reason creates the cookie JSESSIONID
although I never ask it to
HttpSession jsession = request.getSession();
you are requesting a session here and JSESSIONID cookie is created by the container in response
how to create session correctly request.getSession(true? / false? / nothing?);
request.getSession() and request.getSession(true) are exactly the same they start a new session if needed ,but request.getSession(false) means if there is already a session use it but if there isn't don't start one.
How and where you want to start the session is dependent entirely on your requirements
response.addCookie(new Cookie("JSESSIONID", jsession.getId()));
you are not suppossed to add a JSESSIONID cookie yourself , the container will do it for you .
Also you should create session once in your app , once the JSESSIONID cookie is stored in the user's browser(provided cookies are enabled) ,it will be sent along with the request.
How do I implement user authentication
Highly subjective and depends on requirements , you can read this https://docs.oracle.com/cd/E19226-01/820-7627/bncby/index.html
keep the user logged in throughout the session
Your session cookies will help you with that once the user has been authenticated ,as an example login to facebook and keep your cookies tab open

Wicket and servlet filter authentication - is there a better way?

Our application is using Wicket. We're using Wicket's own forms to handle authentication, the main benefits being that the look of the site is kept consistent.
We thought we couldn't do container authentication because our application allows the user to switch authentication mechanisms mid-stream, and Jetty itself was creating quite a bit of friction anyway, just getting simple authentication to work at the container level.
So we ended up implementing authentication via a filter (there are a number of good examples out there.)
Now I have discovered that by doing this, Wicket authentication is slightly broken. What happened was:
Anonymous user would visit the site.
Security filter determines that the user isn't authenticated and redirects to sign-in.
Wicket renders the sign-in page.
User signs in.
Wicket processes the post to the sign-in form and redirects user back.
Security filter determines that the user isn't authenticated and redirects...
I looked inside my subclass of AuthenticatedWebSession, hoping to find some way I could get a hold of the HttpSession and set a session attribute which could then be checked from the filter. However I couldn't for the life of me find a way to do it.
What I resorted to doing was making yet another filter, coded like this:
public class StealWicketUserFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
// Nothing to initialise.
}
#Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException
{
filterChain.doFilter(servletRequest, servletResponse);
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
if ("POST".equals(httpServletRequest.getMethod()) &&
"/sign_in".equals(httpServletRequest.getRequestURI())) {
HttpSession session = httpServletRequest.getSession();
ServerUser currentUser = (ServerUser)
session.getAttribute("wicket:webUIServlet:currentUser");
if (currentUser != null) {
session.setAttribute(CombinedSecurityFilter.CURRENT_USER_ATTRIBUTE,
currentUser);
}
}
else if ("/sign_out".equals(httpServletRequest.getRequestURI())) {
HttpSession session = httpServletRequest.getSession();
session.removeAttribute(CombinedSecurityFilter.CURRENT_USER_ATTRIBUTE);
}
}
#Override
public void destroy() {
// Nothing to destroy.
}
}
This of course works (and will continue to work until Wicket change the prefix they store session attributes under.)
I guess what I want to know is whether this is a bad idea and whether there is a "proper Wicket way" to do this sort of thing.
As for the reason we don't use Wicket's authentication alone - the reason is that we wanted to support SPNEGO authentication and potentially other external authentication types.
You can get hold of your HttpSession,albeit through Request and not Session.
What you need is:
WebRequest req = (WebRequest)RequestCycle.get().getRequest();
HttpSession session = req.getHttpServletRequest().getSession();
However I'm pretty sure Wicket authentication isn't broken in such an obvious manner so I'd probably try to find out what is causing this glitch instead.

How cancel a cookie in spring security?

i am using spring security for authentication and if i have 2 servers (server1, server2) using the same file war.
the User A make login in server 1, saving data on persistent_logins table. If the user A makes refresh on server 2, is automatically logged. This is correct but if the u*ser A (server1)* makes logout, the data of table persistent_logins is removed and the user A(server 2) when makes refresh, still connect.
What i can do to user A(server 2) change to logout mode?
thanks
If you know how to catch the moment when you need to make user_A log out, you may consider using filters and clearing the current session.
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// skip non-http requests
if (!(request instanceof HttpServletRequest)) {
chain.doFilter(request, response);
return;
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
httpRequest.getSession().invalidate();
...
If you need to inject some beans using spring, you may have a look at DelegatingFilterProxy
The easiest solution update data on both server when user logout

How do I get a servlet container to read JSESSIONID from the query string rather than from the URL

I need to be able to maintain a session by having the JSESSIONID specified as a parameter of the query string of the url rather than part of the URL itself.
I other words I need to maintain a session like this
http://myserver.com?jsessionid=A463B23BC4F2342FA
rather than
http://myserver.com;jsessionid=A463B23BC4F2342FA
For a servlet container I'm using both tomcat 6.0 and weblogic 10.3
Reason:
I'm creating a Google Earth network link which requires me to keep a session for the requests a client makes. Google Earth doesn't support cookies and it appears there is no way to change the url that it uses to make requests. I can only tell it to append a query string parameter on subsequent requests by adding the following to the kml in my server responses
<NetworkLinkControl>
<cookie>JSESSIONID=A463B23BC4F2342FA</cookie>
</NetworkLinkControl>
Not possible. I'd create on your side a filter which redirects the request to the proper URL whenever an URL arrives with the JSESSIONID in the query string.
Basic kickoff example:
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if ("GET".equals(request.getMethod()) && request.getParameter("JSESSIONID") != null) {
response.sendRedirect(request.getRequestURL().append(";JSESSIONID=")
.append(request.getParameter("JSESSIONID")).toString());
} else {
chain.doFilter(request, response);
}
}
Map this on an URL pattern which covers requests which could potentially originate by that site. Or if there is none, just on /*.
We have created custom Tomcat Valve for this purpose. It's pretty straightforward, but Tomcat-specific.

Categories