Filter pages with dojo/struts2 - java

I have dojo views eg.: /app/#dashboard, /app/#login etc..
I would like to write a filter which is navigate back to my /app/#login when the user is not authenticated.
The problem is i can't write an url-pattern to the web.xml which can interpret the dojo view's URL after the # mark.
So the application is redirecting to the login, and from there again to the login infinitely. If write url pattern eg.: /app/#dashboard nothing happens, the filter won't called.
In the filter the url is every time /app/ without the # part.
How can i filter out certain dojo views?

Related

Conditional Authentication: How to conditionally display login on page servlet

I am running Tomcat 8. Currently I have pages that users always need login to see, and pages that the user never has to login to see. I have both of these cases working.
But now I need to make a page that users SOMETIMES have to login to see (based on the data/configuration of what is being asked for).
Given that, I can't just throw the servlet endpoint in the web.xml web-resource-collection, it wont work that way.
I have tried returning a login view from my servlet, with the standard wiring for j_securtiy_check, but when the service comes back it does not look like the login worked.
To get around my issue, here is what I did.
In my servlet, I grab the data for the object I need to render, if the object states the user needs to be authenticated to view, I check the authentication with request.getRemoteUser().
If no user is found, I redirect to a secure url with a new servlet. The url will have a ?return=myurl in the url. In this case, the login page displays and the new servlet sees the return url and redirects back to the original page.
The original page now does user lookup again, but this time the user is logged in.
This is not the ideal solution, but it does work.

Using JSF 2.0 / Facelets, is there a way to attach a global listener to all AJAX calls?

Is there a way to attach a global listener to all AJAX calls in JSF? Maybe through a phase listener or something?
Here is the conundrum... Lets say you're using f:ajax tags and something like apache shiro and you let your session expire. Then you come back and click a button that has an f:ajax attached to it. The server will respond with a 302 redirect to the login page.
The user sees nothing. They can repeatedly click and invoke the ajax call, but to them the app is just "dead."
So, my though is, is there a way to attach a listener to all ajax calls in JSF? If so, what I'd like to do is monitoring the response code. If it's a redirect, use a window.navigate to send them along their way.
I'm always open to hear how others have solved this problem!
Is there a way to attach a global listener to all AJAX calls in JSF? Maybe through a phase listener or something?
Yes, a PhaseListener can do it. A SystemEventListener also. A Filter also.
If you're inside JSF context, then you can check as follows whether the current request is an ajax request or not.
if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) {
// It's an ajax request.
}
If you're not inside JSF context, e.g. inside a Filter, then you can check as follows whether the current request is a JSF ajax request or not.
if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
// It's a JSF ajax request.
}
Here is the conundrum... Lets say you're using f:ajax tags and something like apache shiro and you let your session expire. Then you come back and click a button that has an f:ajax attached to it. The server will respond with a 302 redirect to the login page.
The user sees nothing. They can repeatedly click and invoke the ajax call, but to them the app is just "dead."
Forcing a redirect on an ajax request requires a special XML response. When you're inside JSF context, then ExternalContext#redirect() already takes this implicitly into account. All you need to do is to write this:
FacesContext.getCurrentInstance().getExternalContext().redirect(url);
If you're not inside JSF context, e.g. inside a Filter, then you'd need to write the whole XML response yourself. E.g.
response.setContentType("text/xml");
response.getWriter()
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", url);
To redirect a jsf ajax request you need xml as follows
<?xml version="1.0" encoding="UTF-8"?>
<partial-response>
<redirect url="XXX">
</redirect>
</partial-response>
Here XXX is url you want redirect to happen.
On ajax call redirect sent is not as above hence no redirect.
To get the desired result have a filter for all jsf request except few
pages(login page) and check session is valid and if it is really jsf
ajax call by checking header "Faces-Request", its value should be
"partial/ajax". If session has expired and is ajax request send above
xml as response.
It should work.

<c:url> tag analog in Play framework

Is there any analog of jstl url tag, which can be used to generate valid URL, independently of current template location or application location.
For example, #{a #Application.logout()}Disconnect#{/a} simply generate /application/logout URL.
But i'm looking for a tag that will generate me /logout URL. This url will point to Application.logout() method in routes file
If you use
Logout
Then play will generate your url relatively for you. You can also use:
Logout
to generate absolute urls.
If you want to customize the url to be used go to the routes file and add e.g
/logout Application.logout
Ok. just realized why this tag generate /application/logout instead of logout. It's because of this in routes file
# Catch all
* /{controller}/{action} {controller}.{action}
If i delete it or move below logout defenition, everything works fine
Just write #Application.logout() to get the URL.
In your case:
Logout

Recording url navigation history

Goal: User tries to access page without authentication. Site redirects to login page, when they enter details they are returned to the page they were trying to access.
I have a filter which records the last url the user was at in the session. The following code is how i get the uri.
String uri = request.getRequestURI().toString();
String queryString = request.getQueryString();
String completeUri = uri;
if (queryString != null)
{
completeUri += "?" + queryString;
}
In practice this filter seams to be catching external css files, individual images on a page etc so about half the time it works and half the time its pointing to an image or css file.
The mapping for the filter is...
<filter>
<filter-name>ComprehensiveFilter</filter-name>
<filter-class>core.website.control.filter.ComprehensiveFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ComprehensiveFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
So question is. Why does my code store images and external files instead of the url the user was just at? I assume it has something to do with my mapping of the filter.
You should use this code only in case you detect unauthorized access and redirect to the login page. And you should pass it as param, like response.sendRedirect("login.jsp?" + completeUri)
Now, if the filter is applied to every resource (as you do), it will be triggered for images and css files that are included in the login.jsp. You must exclude the login.jsp itself from this redirection (otherwise you will enter a loop), and you must also exclude the css files. This depends on your URL scheme.
if all your pages are .jsp, then map the filter to *.jsp
if your actions to through a single servlet (like a dispatcher servlet), then map the filter to that servlet (instead of <uri-pattern> set <servlet-name>)
if you have "pretty urls", then (in the filter) check if the requested resource ends with .css, .png, .gif etc, and don't enter the redirection logic.
When you have any images on the page, meaning an html <img> tag, then the tag's src attribute refers to an actual URL (see http://www.w3schools.com/tags/tag_img.asp). So when the page is loaded, the browser sends out another request to load that image. Your filter also catches not only the request for the entire page, but also those image loading requests.

Login page redirection in Java and Javascript

Ok, so I've got an interesting case of login page redirection going on.
My webservice has a login page (login.html) with some javascript to handle logging in and redirecting to a hardcoded 'default' page. The webservice is written in Java with a servlet filter handling redirection if a user is unauthenticated (so if a user tries to access domain/statistics without being logged in, they are directed to domain/login.html). The redirection from the protected services works: I can redirect to the login page and once a user is authenticated, redirect them to a default page. I am having issues, however, redirecting to the previous page.
I know this is usually handled with the argument document.referrer in the Javascript, which I have tried, but due to the Java's redirection with response.sendRedirect, the Referer header is not sent.
How can I get these two aspects to redirect to the previously called page? Is it something I need to add on the Javascript side, the Java side, or both?
What I've done is to drop the original (redirected) URL into a hidden input field on the login form. The code that does the authentication should just check that parameter, and if it's not empty it can redirect after establishing the session.
You have to be careful doing this to prevent XSS attacks etc., but it's not that hard and it works just fine.
In my framework (Stripes), I can push the original URL (taken from the HttpServletRequest object, a combination of the servlet path, the "path info", and the query string) into a special holding box that will cause the framework to give it back to me on the next request as a parameter. Without that, the simple thing to do is add the URL as a parameter when you redirect. Just URL-encode the original attempted URL and tack it onto the redirect URL with some parameter name. Then, on your login page, you just check for it:
<c:if test='${not empty param.attemptedUrl}'>
<input type='hidden' name='attemptedUrl' value='${fn:escapeXml(param.attemptedUrl)}'>
</c:if>
Then your login action will get that parameter too when the login form is submitted, and it can act on it as appropriate.
Send Redirect will ask to the client to repeat the request to the resource you choose. Have you think of Spring Security with minimal configuration you can achieve this quite easily.
Take a look at this:
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html

Categories

Resources