How to write servlet filter to destroy all cookies related to domain on browser - jsf

I am new to servlet filter.
I am using JSF 2.2, Wildfly 8.1. I have figured out that if user clicks log out link when session is already expired then when user logs in again the system will continiously fire exception of session expired. BalusC wrote to write servlet filter which will delete all cookies of specific domain before user will see welcome page.
How to write servlet filter which will destroy all cookies related to specific domain (domain.com) when new session will start? I played with it and absolutely confused. sorry for my a little experience in jsf.

I think you need to set cookie.setMaxAge(0);for all the cookie for that domain.
Inside your filter(which should be used for Logout request only) or in Logout servlet(if any) you can write below line to delete all cookie.
Cookie[] cookies = req.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
cookie.setValue("");
cookie.setPath("/");
cookie.setMaxAge(0);
resp.addCookie(cookie)
}
}

Related

Java EE Container based Certificate authentication logout

In our Java EE application we use container based certificate authentication. We have created JAASLoginModule, which implements LoginModule interface with all required methods. We have configured our Wildfly and TomEE server to use this module both for authentication and ssl channel security, and everything goes smoothly with user login:
the user opens the browser and the app;
selects a certificate;
a JSF session is created, and now he is logged in;
A different story is with the logout. Just destroying the JSF session is not enough - after logout, if you just click back, the browser will get the certificate info from cache, recreate a session and lets you do the same stuff. Sometimes even browser restart does not help.
I could not find an effective way to call the logout method from the LoginModule from the JSF managed bean.
Any way to solve this problem?
Your problem is directly with the browser, so what you need is to tell the browser to "restart" the cache from your page every time it logs out, this, in order for it to think it's the first time the client is trying to get into that page. Kind of the same that private windows in Chrome and Firefox do.
Try this code:
//...
response.setHeader("Cache-Control","no-cache"); //Forces caches to obtain a new copy of the page from the origin server
response.setHeader("Cache-Control","no-store"); //Directs caches not to store the page under any circumstance
response.setDateHeader("Expires", 0); //Causes the proxy cache to see the page as "stale"
response.setHeader("Pragma","no-cache"); //HTTP 1.0 backward compatibility
//can check userId or something likes this.In this sample, i checked with userName.
String userName = (String) session.getAttribute("User");
if (null == userName) {
request.setAttribute("Error", "Session has ended. Please login.");
RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
rd.forward(request, response);
}
Source: How to clear browser cache using java

JSF to Bean to JSF

So I'm having a problem trying to pass a String value.
The String value is entered through a login page as username.
The JSF then calls the Bean to verify log in information then proceeds to another JSF page.
I was wondering how to pass the username along to the new JSF page. Thank you.
If you're performing a navigation instead of a redirect, then you basically don't need to do anything. The information is also just available in the navigated page.
E.g. in login page,
<h:inputText value="#{bean.username}" />
and in the navigated page:
<p>You have entered the following username: #{bean.username}</p>
If you're however performing a redirect instead of a navigation, then you basically need to store the information in a bit broader scope. You didn't clearly elaborate the concrete functional requirement in the question, but if I guess it right, you just wanted to remember the currently logged-in user for the remaining of the HTTP session. In that case, just store it in the session scope during the login action.
public String login() {
// ...
User user = userService.find(username, password);
// ...
externalContext.getSessionMap().put("user", user);
// ...
return "nextpage?faces-redirect=true";
}
This way it's available by #{user} throughout the entire HTTP session.
<p>You're logged in as #{user.name}.</p>
You can also use <t:saveState> without using session scope. <t:saveState> is longer than the request scope but shorter than session scope.
This may help you : http://myfaces.apache.org/tomahawk-project/tomahawk12/tagdoc/t_saveState.html

How to signout programmatically from Liferay custom portlet

I am creating a custom portlet.
And I need to log-out the User from the portal after he performs some operation in my custom portlet. I am extending liferay's MVCPortlet.
In one of MyPortlet's action methods I need to write the code to logout the user and then redirect it to the home page.
Update:
I tried the following which I think logs out the user but does not redirect to the home page after logging out:
actionResponse.sendRedirect(PortalUtil.getPortalURL(actionRequest) + "/c/portal/logout");
Thanks All
Well this may be a very late reply, but it may help somebody
Firstly, you have to validate the session and the re-direct to the logout URL. Otherwise, the session remains and the user is moved to the landing page, even though we redirect to the logout url. So, this is what one should do
HttpServletRequest request = PortalUtil.getHttpServletRequest(actionRequest);
request.getSession().invalidate();
actionResponse.sendRedirect(themeDisplay.getURLSignOut());
Hope this helps.
I also did not find a way to send a specific redirect by using liferay's default logout (/c/portal/logout). So I logged out the user programmatically with the util class AuthenticatedSessionManagerUtil and
afterwards sending a specific redirect location within the response object, e.g. response.sendRedirect(yourLocation)
Note:
With Liferay 7.2 I used AuthenticatedSessionManagerUtil.signOutSimultaneousLogins(userId) instead of AuthenticatedSessionManagerUtil.logout(userId) which did not work for me.
hth
You can redirect to c/portal/logout
more precisely :
actionResponse.sendRedirect("/c/portal/logout/");
Just leaving this here after facing this problem (LR7):
try {
AuthenticatedSessionManagerUtil.logout(request, response);
request.setAttribute(WebKeys.LOGOUT, true);
}
All you have to do is
perform operation: at the end of operation use this:
HttpSession session = PortalUtil.getHttpServletRequest(request).getSession();
session.invalidate();
try {
System.out.println(" redirecting to the required page");
response.sendRedirect(themeDisplay.getPortalURL() + "/page-on-which-to-be-redirected");
} catch (IOException e1) {
e1.printStackTrace();
}

How to detect session has been invalidated in JSF 2?

In my application I have a quit button, on clicking of which the session for the current user is invalidated by the following piece of the code..
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
And I redirect the user to a different page.
But now I want if user click on the back button I will take him to the start page of the application instead of the last page visted by him.
I have an application phase listener which sets the page cache related headers to 'none', now all I want is to detect that for that user session has been invalidated.
But I guess whenever the user is clicking the back button it is creating a new session for the user. Is there any way to prevent it?
How to detect session has been invalidated in JSF 2?
Check if the user has requested a session ID which is not valid.
HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
// Session has been invalidated during the previous request.
}
it is creating a new session for the user. Is there any way to prevent it?
Just don't let your application code create the session then. The session will implicitly be created when your application needs to store something in the session, e.g. view or session scoped beans, or the view state of a <h:form>, etc.
I have an application phase listener which sets the page cache related headers to 'none'
A servlet filter is a better place for this. See also Avoid back button on JSF web application

Redirect loop when liferay integrated with OpenSSO

My softwares are:
Liferay 6.0.6 with Tomocat 6.0.29, OpenSSO 9.5.2_RC1 Build 563 with tomcat 6.0.35, CentOS 6.2 Operating system
Setup:
I have setup both liferay and opensso on the same CenOS machine, making sure that both of its tomcat run on very different port, I have installed and configured OpenSSO with Liferay as per the guidelines availaible on liferay forums
Problem:
when i hit my application URL i get redirected to Opensso login page which is what i want, when i login with proper authentication details it trys to redirect to my application which is exactly how it should behave, however this redirect goes in a loop and i don't see my application dashboard. The conclusion i come to is that the redirect is trying to authenticate in liferay but somehow it does not get what it is looking for and goes back to opensso and this repeats infinitely. I can find similar issues been reported here. Unfortunetly, it did not work.
Later i decided to debug the liferay code and i put a break point on com.liferay.portal.servlet.filters.sso.opensso.OpenSSOUtil and com.liferay.portal.servlet.filters.sso.opensso.OpenSSOFilter. The way i understand this code is written is it first goes to the OpenSSOUtil.processFilter() method which get's the openSSO setting information that i have configured on liferay and later checks if it is authenticated by calling the method OpenSSOUtil.isAuthenticated(). This particular implementation basically reads the cookie information sent and tries to set the cookie property on liferay by calling the method OpenSSOUtil._setCookieProperty(). This is where it fails, it tries to read the cookie with name [iPlanetDirectoryPro] from the liferay class com.liferay.util.CookieUtil using the HttpServletRequest object but all it get's a NULL. this value set's the authenticate status to false and hence the loop executes.
Following is the code from class com.liferay.util.CookieUtil
public static String get(HttpServletRequest request, String name) {
Cookie[] cookies = request.getCookies();
if (cookies == null) {
return null;
}
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies;
String cookieName = GetterUtil.getString(cookie.getName());
if (cookieName.equalsIgnoreCase(name)) {
return cookie.getValue();
}
}
return null;
}
Can anyone please let me know why liferay is not able to find the cookie that opensso sent. If its related to Opensso setting about enable cookie value, then i have done that already which is here
In OpenSSO go to: Configuration -> Servers and Sites -> -> Security -> Cookie -> check Encode Cookie Value (set to Yes)
What works:
when this loop is executing i open another tab and login to my application explicitly, from my application when i signout it get's signout from opensso also. This is strange to me.
For more information, while this redirect loop happens, following URL's give me these set of information
http://opensso.ple.com:9090/openam/identity/getCookieNameForToken
string=iPlanetDirectoryPro
http://opensso.ple.com:9090/openam/identity/isTokenValid
boolean=true

Resources