How can I check for authorization in JAAS during request - java

I have implemented form authentication as offered by JAAS. Since I process all my pages as templates code has to be evaluated every time. Thus when the user is directo to /login the doGet request has to handle it and process the login template.
Now I would like to redirect to the main page after the login was successful. When the user chooses /login again he/she should be redirected to the main page.
Thus I need to know during a doGet request whether the user is authorized, maybe also which authentication. How can I check? Or is this idiom wrong?
Or is this done by request.isUserInRole(String role)? Since it does both, authentication AND authorization?

You can check if an user is logged in by checking if HttpServletRequest#getRemoteUser() (the user name) or #getUserPrincipal() (the associated Princpal object) does not return null.
So, e.g. in doGet() of the /login servlet you could do this:
if (request.getRemoteUser() != null) {
// Already logged in, so redirect to some main page.
response.sendRedirect(request.getContextPath() + "/main");
return;
}
// ...
The #isUserInRole() only checks if the logged-in user has some specific role and this is usually only useful to restrict some pages or page sections for specific roles. So unless you've a general role which is shared by every user, this isn't useful.
You may only want to add a message to inform the enduser why s/he is been redirected and what's the proper way to login again as another user. E.g. "You are already logged in. If you need to login as another user, please go to logout page first." or so in the main page which is conditionally displayed based on some redirect parameter.

Related

Block the user request from URL

I need to implement a logic in my project to block the user request from the URL bar, let say user is in middle of one module and user wants to resubmit / refresh the page, in normal web applications user can Go to URL bar press enter. But in my project we need to block the user to send the request from URL bar and redirect the page to Page / Session Expired page .
I think we can achieve this by using a servlet filter by checking the request , whether the request is coming from URL bar or a form. Is there any way to check where the request is coming from ?
Use any Random Token Number generated with URL request and every time validate the token.
Just apply authentication filter to restrict access to other pages,if user try access the unwanted page make him land on your desired page.

webpage authentication in jsf

I'm having a problem in identifying a session timeout page and a page navigated directly...
user will first fill a form and submits it, based on the search he will land on information page. for some reason if he try to type the url of information page instead of coming through search page how can i restrict him?
i tried using an indicator varaible in session, but that is getting in conflict with session timeout.... how do i differentiate if it is session timeout or direct navigation?
could someone please shed some light on this and point me in right direction?
From my understanding your question is:
User should not be able to access a certain page say Page1.xhtml directly. He should first fill in a form on page2.xhtml and then should be directed to this page by the server itself.
Solution:
You could put the page1.xhtml inside web-inf directory of your webapp, which will restrict direct access to your webpage.
You could you use securityConstraint tag of the web.xml and make use of container security to restrict direct access.
You could test for a server side session timeout as follows:
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
// The session has been timed out (or a hacker supplied a fake cookie).
}
The request is here the HttpServletRequest which you can obtain in the JSF context from the ExternalContext#getRequest() or, actually better, inside a Filter by just downcasting the ServletRequest argument.
As a completely different alternative, you could also introduce a timed ajax poll as a "heartbeat" so that the session never expires as long as the user has the page open in the browser.

Spring MVC strange behavior

I have a method that handles request with a URI of "/home". This request is generated upon successful log-in procedure. Here is a little code to support my situation:
<security:form-login login-processing-url="/static/j_spring_security_check"
login-page="/login" authentication-failure-url="/login?login_error=t"
default-target-url="/home"/>
The method body demonstrates what I am attempting to achieve:
String userMail = SecurityContextHolder.getContext().
getAuthentication().getName();
logger.info(userMail);
Person p = userService.retrieveUserByEmail(userMail);
session.setAttribute("person", p);
return "user/home";
This bit is important as the person p is used as data source for other requests.
Now the problem. I don't know if it is the property of Google Chrome, but for some reason the browser remembers the request you've done before log-in and instead of going through /home request after successful log-in procedure, it generates the previous request bypassing this /home gate, resulting in null pointer exception as person p was never set up, as session wasn't populated by /home request.
I know that for other requests I should do validation, but I don't like the idea of letting user generate any request without prior going through /home .
Done with text description and now to explain how I get unwanted behaviour in steps:
ask for request that you know exist such as:
myApp/nameOfSomething/viewThisSomething - you are brought to log-in page as expected(you must be authenticated for request to be accepted)
you enter correct credentials and instead of going to default-target-url="/home"
you are automatically making previous request myApp/nameOfSomething/viewThisSomething without populating session with necessary data and resulting in nullpointer exception.
What else is interesting is that logger shows the mail, so it might be that they are both executed at the same time but /home request is slower - can that happen?
I resolve the situation in other method by checking if null and forcing to go back to /home which works as expected, but I am control freak and don't like when user is doing what he is not intended to do.
Thank You for Your time,
It's not a bug, it's a feature. It's much more user-friendly to let the user go where he wants to go after login than forcing him to go to the home page. He could have bookmarked one of the protected pages, or simply browsed some non-protected pages containing a link to a protected page.
From http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ns-form-target:
If a form login isn't prompted by an attempt to access a protected
resource, the default-target-url option comes into play. This is the
URL the user will be taken to after successfully logging in, and
defaults to "/". You can also configure things so that the user always
ends up at this page (regardless of whether the login was "on-demand"
or they explicitly chose to log in) by setting the
always-use-default-target attribute to "true"
IMHO, you should keep things as is, but make sure that the required sesion attribute is set once the login is successful, instead of setting this attribute in the home page. This would ensure that every protected page has access to the session attribute, even if the user didn't go to the home page.
You could do this easily by using a custom UsernamePasswordAuthenticationFilter subclass, that sets the appropriate attribute in session once the authentication has succeeded.

Java Servlet redirecting from one Servlet to another and then back to the initial Servlet

I had a question about Java Servlets.
lets say I am on a servlet webpage, 'somePage'. I want to log in (using another servlet, 'login' servlet). So i click on the log-in link on the 'somePage' and get redirected to the 'login' page. I type in my name and password and they are both correct. the login page has successfully logged me in.
(now asking about coding for the 'login' servlet) How do I code the 'login' page so that it will redirect the successfully logged in person back to the, 'somePage' webpage?
Main Question: How does the login page know the page which initially redirected to it is the 'somePage' page?
I have checed out a lot of the request parameters, but non tell me, yes, you were directed from page, 'somePage'. These are the the paramater i have looked at:
String authType = request.getAuthType();
String pathInfo = request.getPathInfo();
String pathTranslated = request.getPathTranslated();
String getUserName = request.getRemoteUser();
String remoteAdd = request.getRemoteAddr();
String uriString = request.getRequestURI();
String sessionID = request.getRequestedSessionId();
String serverName = request.getServerName();
Integer serverPort = request.getServerPort();
String servletPath = request.getServletPath();
I know some of these are obvously not going to give me the answer I am looking for, but I figure one of the HttpServletRequest parameters has got to tell the login page who asked for it to be displayed. Any help would be greatly appreciated. I'm going to continue my search for the answer. I've tried to search for this question, but haven't found an answer.
Instead implementing yourself you should consider using form based authentification for your web app.
Almost every servlet container supports this.
At first you have to configure security. This depends on your application server. I.e. with Jetty you can use a database approach with tables for users and their roles or LDAP, etc.
In web.xml you turn on form based authentification:
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/logon.jsp</form-login-page>
<form-error-page>/logonError.jsp</form-error-page>
</form-login-config>
</login-config>
You specify two JSP pages you have to provide. logon.jsp is the login page for inserting user name and password. logonError.jsp is shown, if user name and password are invalid.
The whole login workflow is handled by the application server.
If the user first goes to a protected URL, the application server presents the login page instead. As a convention the input fields for user name and passwort should be named j_username and j_password. When the user submits the login form the server checks, if the user crendentials are valid (according to its configuration). If so the user is redirected to the original page. Otherwise the login error page is shown.
If you really want to implement it yourself then you can implement a servlet filter so that all calls to protected resources have to pass your filter.
In your filter you can check, if there is already a session present and if the user has successfully logged in. Then the normal call can proceed. Otherwise you can forward to your login page and store the original URL in the session. After a successfull login you can read the original URL out of your session context and redirect to the page the user wanted to see in the first place.
There are different ways of doing this. One way is to have your login page support a continue CGI parameter that gives the URL to which to redirect after the login is successful. Another way to do this is to use the "Referer" header that was passed to the login page, and redirect to that URL.
For the former, you can use ServletRequest.getParameterMap() to get the CGI arguments and determine if there is a CGI parameter named continue (or whatever name you choose to give to that CGI parameter); for the latter, you can use HttpServletRequest.getHeader() to get the "Referer" header.

Java Web App Security using Cookies

I'm finishing a Cattle Drive assignment where a small Java web application manages a movie library for the client. The assignment is to put some security on the application using cookies, so that a "hacker" couldn't just guess one of the URLs that would lead to another part of the application. The user will be directed to login to the site and not be allowed to view other pages until logged in.
The parts of the web app are:
1. index.html
2. VideoServlet
3. listvideos.jsp
4. addvideo.jsp
5. videologin,jsp
The entry point is request URL http://localhost:8080/videos, which loads the index.html file. This page just has a link which redirects the user to the VideoServlet. From there, the servlet forwards the HTTP request and response to listvideos.jsp, which has a link to add videos if the users wants to do that.
I'm having trouble understanding how to implement the security using cookies, while keeping everything in the MVC2 pattern (the servlet is the controller, the jsp's are the view).
Here is the program flow I came up with, but I think I'm missing the point somewhere:
user enters URL http://localhost:8080/videos, which pulls the index.html file by default.
the index.html file basically sends an HTTP Get to VideoServlet. The servlet somehow knows the user isn't logged in yet, so forwards the request/response to the videologin.jsp.
a login is presented and asks the user for a password (this is a standard html form). The user enters the password and clicks submit. This sends an HTTP Post to the servlet.
the servlet checks the password and if correct, the user is logged in and the servlet forwards to listvideos.jsp.
I don't get where cookies come in or how they can help prevent a hacker from guessing a URL and gaining direct access to, for example, addvideos.jsp. Is a cookie being used to verify if the user has already logged in?
Cookies are some plain text values (stored in text files in browser cache normally) that you could use to store data on client side. When the user makes a request to a particular URL, all cookies stored on that server (domain) are passed with it, so that the server can read up those values.
In Java, you can set a cookie like this in your servlet (in your case, when user logs in, create a cookie and store a value in it (ex. username=josh). You could do this in your login servlet after a successful login.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Verify login, and get the username. Assume it's josh
Cookie cookie = new Cookie("username", "josh");
cookie.setMaxAge(60*60*24); // 24 hours for expiry
response.addCookie(cookie);
}
Later on, you can check for the existence of the cookie and if it exists, then the user has logged in. If not, you can send a redirect to the login page.
You can check for cookies like this in your servlet.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cookies = request.getCookies();
String username = null;
for (Cookie c : cookies) {
if ("_username".equals(c.getName())) {
username = c.getValue();
break;
}
}
if (username == null) {
// Not Logged in. Redirect to Login
}
// User Logged In. Proceed
}
Instead of putting this code in all your Servlets + JSPs, you can easily put this into a Servlet Filter class. You can read up on more on that here: http://javaboutique.internet.com/tutorials/Servlet_Filters/
Ideally, you could provide a Logout feature also, which will remove the value assigned to the username cookie by replacing it with null.
I showed the above example because you mentioned that you need to use cookies for your assignment. But if you can, try to use the Sessions (which in turn uses cookies most of the time) to store logged in user details. With sessions, you can use session timeouts to ensure that idle users will be automatically logged off after a while and so on.
the index.html file basically sends an HTTP Get to VideoServlet. The servlet somehow knows the user isn't logged in yet, so forwards the request/response to the videologin.jsp.
The somehow knows is due to looking for the presence of the cookie in the request. Make sure the contents of the cookie are protected by a message authentication code, so you can be sure that your server actually handed out the cookie. It'd also be a good idea to encode into the cookie the specific IP address being used by the client, so an attacker can't hijack a cookie. (If a client changes IP address during a session, requiring them to log in again isn't horrible. Maybe annoying, but not unexpected.)
the servlet checks the password and if correct, the user is logged in and the servlet forwards to listvideos.jsp.
the user is logged in -- set the cookie into the browser for future requests.

Categories