Java JSF redirect on logout - java

I have a ViewScoped JSF page. There exists an ace:dialog where the user is working in. If the user does not click for two hours, his session becomes automaticly destroyed by tomcat.
If the user send a request after that two hours, I redirect to the login page (because the user is logged out). Problem is that I become an error:
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
Is there a way to redirect every request to the login page if the user become logged out?
What happened to my Backing Beans if the session got destroyed?
Thats the way of my redirect if the user is request a subsite and is not logged in:
#PostConstruct
public void initialize() {
logger.debug("Start - " + new Throwable().getStackTrace()[0]);
if (hasReadAccess()) {
FacesContext.getCurrentInstance().getExternalContext().redirect(pPath);
return;
}
logger.debug("End- " + new Throwable().getStackTrace()[0]);
}
That is the way of my code, if the user sends a ajax request, for example using a rowEditListener:
public void rowEditListener(RowEditEvent ev) {
logger.debug("Start - " + new Throwable().getStackTrace()[0]);
if (hasReadAccess()) {
FacesContext.getCurrentInstance().getExternalContext().redirect(pPath);
return;
}
// do something
logger.debug("End - " + new Throwable().getStackTrace()[0]);
}
Thanks!

you can use spring:
public void logout() {
try {
SecurityContextHolder.getContext().setAuthentication(null);
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
FacesContext.getCurrentInstance().getExternalContext()
.redirect(FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath() + "/j_spring_security_logout?faces-redirect=true");
} catch (Exception e) {
}
}

Related

Adobe AEM - How can I return a custom error page after a post fails?

I've created an overwriting of the foundation Forms where I'm trying to return an error page that is configured by the author within the component
In other words, the flow would be:
- author configure error page
- the end user submits the form
- the form process fails
- aem returns the error page configured by the author with status 500
at the moment i've overwritten the forward.jsp. JSPs that are used by the different Foundation Form actions. This jsp performs a forward to the servlet that processes the data entered by the end user, here is the line that performs the forward:
FormsHelper.setForwardPath (slingRequest, resource.getPath () + "." + Constants.SERVLET_SELECTOR + ".html");
On the servlet i have a code similar to:
String errorPage = request.getParameter(":errorPage");
...
if (StringUtils.isNotBlank(errorPage)) {
response.reset();
response.setContentType("text/html");
response.setStatus(statusCode);
final RequestDispatcher dispatcher = request.getRequestDispatcher(erroPage);
if (dispatcher != null) {
try {
dispatcher.include(new GetRequest(request), response);
} catch (Exception e) {
logger.debug("Exception swallowed while including error page", e);
}
}
private static class GetRequest extends SlingHttpServletRequestWrapper {
public GetRequest(SlingHttpServletRequest wrappedRequest) {
super(wrappedRequest);
}
public String getMethod() {
return "GET";
}
}
It seems to work, but since it is a forward, the parameters are sent to the response, which would not be necessary and i think a bad practice.
What would be the correct way to do it without making a forward, being able to return the error page and with status 500 in the response.?

How to authenticate logged in user when refreshing single page application using AngularJS without "Routing"?

I searched a lot of resources but none was appropriate to my problem.I am working on single page application (SPA) project ,and I want a logged in user to stay logged in whenever he refreshes the page but without routing.
I have tried to call session authentication servlet in the main controller of the page(this servlet checks whether the session exists or not),but it did not work.
Note: The session is created once the user log in or sing up.
Here is SessionAuthServlet.java:
HttpSession session = request.getSession(true);
User u=(User) session.getAttribute("usersession");
try{
response.setContentType("application/json; charset=UTF-8");
PrintWriter out = response.getWriter();
if(u != null)
{
out.println("{\"+success+\"}");
out.close();
}
else
{
out.println("{ \"result\": \"fail\"}");
out.close();
}
}catch (IOException e) {
e.printStackTrace();
}
MainController in HTML single page application:
appvar.controller('MianController',['$scope','$http','$rootScope',function($scope, $http,$rootScope) {
$rootScope.sessionvalid=function(){
$http.get("http://localhost:8080/MyProject/SessionAuthServlet")
.success(function(response) {
if (response.result=="fail")
{
//***Show the view for not logged user
}
//***Show the view for logged user
}
$rootScope.sessionvalid();
});
}
}]);
Any ideas how to deal with this?
Please guide me
Thanks
Here is how you can stay logged after page refresh without using routing.
You will need below three things
A angular service to hold user information and if he is authenticated or not.
A window sessionstorage to save user information. Even if the page is refereshed the user information will persist in sessionstorage
An interceptor to set request and response.
Service code -
app.service('AuthenticationService', function() {
var auth = {
isLogged: false,
email:"",
isAdmin:false
}
return auth;
});
In your MainController, once user is logged in set the Service AuthenticationService.isLogged = true and $window.sessionStorage = userInfo
Interceptor code-
app.service('TokenInterceptor', function ($q, $window, $location, AuthenticationService) {
return {
request: function (config) {
config.headers = config.headers || {};
if ($window.sessionStorage.token) {
config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
}
return config;
},
/* Set Authentication.isAuthenticated to true if 200 received */
response: function (response) {
if (response != null && response.status == 200 && $window.sessionStorage.token && !AuthenticationService.isAuthenticated) {
AuthenticationService.isAuthenticated = true;
}
return response || $q.when(response);
}
};
});
and in your app.config block add this -
app.config(function($httpProvider){
$httpProvider.interceptors.push(TokenInterceptor);
})
Now your AuthenticationService.isLogged will remain true even if the page is refershed and you can get the logged in user info in the service.

Handling sessions and remembering logged in user with vertx

Currently when a user logs in to my web server using a web POST form, a custom authenticator and a custom user. I have the CustomUser put into the Session provided by the RoutingContext because, when using RoutingContext#setUser it only changes the user for that request and as soon as the user is redirected from the login processing page to their destination the CustomUser has been lost.
However, it also seems as though the Session in RoutingContext for the new page doesn't have any user stored in the entry where the auth placed the CustomUser, could this be sending a completely different Session?
Routing:
//ROUTE DEFINITIONS
// SESSION AND COOKIE
router.route().handler(SessionHandler.create(LocalSessionStore.create(vertx)).setNagHttps(false)); //TODO SSL
router.route().handler(CookieHandler.create());
// STATIC
router.route("/").handler(new StaticHandler()); //BASE
router.route("/admin").handler(new StaticHandler()); //ADMIN PAGE
// FORM REQUESTS
router.route("/login").handler(new AuthAndRegHandler(new CustomAuth(), dbController)); //LOGIN REQUEST
router.route("/logout").handler(new AuthAndRegHandler(new CustomAuth(), dbController)); //LOGOUT REQUEST
// AJAX
router.route("/ajax/updateInvoice").handler(new AjaxHandler());
// ERRORS
router.route().failureHandler(new ErrorHandler());
router.route().handler(handle -> {
handle.fail(404);
});
//END DEFINITIONS
AuthAndRegHandler:
public class AuthAndRegHandler extends AuthHandlerImpl {
private DatabaseController db;
private CustomAuth authProvider;
public AuthAndRegHandler(CustomAuth authProvider, DatabaseController db) {
super(authProvider);
this.db = db;
this.authProvider = authProvider;
}
#Override
public void handle(RoutingContext event) {
Logger log = LoggerFactory.getLogger(this.getClass());
HttpServerResponse response = event.response();
HttpServerRequest request = event.request();
Session session = event.session();
String requestedPath = request.path();
authProvider.setJdbc(db.getJdbc()); //returns a JDBCClient
if(requestedPath.equalsIgnoreCase("/login")) {
if(request.method() != HttpMethod.POST)
event.fail(500);
else {
request.setExpectMultipart(true);
request.endHandler(handle -> {
MultiMap formAtts = request.formAttributes();
String email = formAtts.get("email");
String pw = formAtts.get("password");
log.info(email + ":" + pw + " login attempt");
authProvider.authenticate(new JsonObject()
.put("username", email)
.put("password", pw), res -> {
if(res.succeeded()) {
CustomUser userToSet = (CustomUser) res.result();
session.put("user", userToSet);
log.info("Login successful for " + email);
response.putHeader("Location", "/").setStatusCode(302).end();
} else {
event.fail(500);
log.error("Auth error for " + request.host());
}
});
});
}
}
}
}
CustomAuth returns true every time for testing purposes.
StaticHandler
CustomUser user = session.get("user");
event.setUser(user);
response.putHeader("Content-Type", "text/html");
if(user != null) {
log.info(user.principal().getString("email") + " user detected");
event.setUser(user);
} else
log.info("Null user request detected"); //Constantly outputs, even after a login form has been submitted
I'm not entirely sure what's going wrong here. Vertx has sub-optimal documentation for a rookie like myself on session and handling things without their out-of-the-box implementations. Any help on how to log someone in and maintain their session like a normal website would be appreciated.
For those who stumble upon the same problem, but usually skip the comments:
Vert.x SessionHandler depends on CookieHandler, and the order is important here.
From the Vert.x examples:
router.route().handler(CookieHandler.create());
router.route().handler(sessionHandler);

Setting a Attribute for Every Request (Spring REST)

I am doing a rest app in spring and i have a log out method like below. I dont have knowledge on spring so i just searched around and made this.
#RestController
public class LogoutController {
#Autowired
private DatabaseService databaseService;
#RequestMapping(value = "/myApp/user/logout", method = GET, produces = {"application/xml"})
public Users performLogout(#RequestHeader("AuthenticationID") String authID, HttpServletRequest request) throws DatatypeConfigurationException {
return handleLogout(request, authID);
}
private Users handleLogout(HttpServletRequest request, String authID) throws DatatypeConfigurationException {
LogService.info(this.getClass().getName(), "Received Logout Request");
final UsersXMLBuilder usersXMLBuilder = new UsersXMLBuilder();
Users usersXML = usersXMLBuilder.buildDefaultUsersTemplate();
HttpSession session = request.getSession();
AppUtilities utils = new AppUtilities();
try {
//Checking with RegEX
if (utils.isValidUUID(authToken)) {
//Get User Login Record from DB By the AuthID and Delete It
//Invalidate The Session
session.invalidate();
LogService.info(this.getClass().getName(), "Session Invaliated");
} else {
LogService.info(this.getClass().getName(), "Invalid AuthID Found. Not a Valid UUID");
usersXML.setResponseCode(-5);
usersXML.setResponseText("User Session is Not Valid");
}
} catch (Exception ex) {
LogService.error(this.getClass().getName(), ex);
usersXML.setResponseCode(-4);
usersXML.setResponseText("Error Occured!");
return usersXML;
} finally {
LogService.info(this.getClass().getName(), "LogOut Process Finished");
}
return usersXML;
}
}
Questions
1- Is it possible i can return a XML message when spring gives white label error page when i pass no authentication ID in request.
2- How can i get the Authentication Header and check it for null and give message that AuthID is missing.
3- How can i set a attribute explicitly and check for it in every controller that if it exists or not.
4- I plan to have a table where i can store user login time and give a session 10 mins time and Update it more 10 mins if i get any request from the user with the AuthID. So can i have a class or method which can check any incoming request? so i can detect the AuthID and Update My table.
Thank you for your time and help.
You can use an interceptor for that : http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor
The interceptor will run for every request. It can stop the request and do a response itself.

Maintaining sessions in mvc dynamic application

I am working on a web application of my own.Iam using Spring-mvc3 architecture n my application.I want to add authentication to my application.I thought of doing it by sessions but am not able to do so.I have created a login page and after login am able to authenticate and go to next page and get data that i have saved during session creation.Then after that when am navigating to another page my session data that i have saved is getting lost and when iam trying to get the session id am getting a new session id which is different from the one the got created at the time of authentication please check this and provide me the appropriate answer.
#RequestMapping(value = "checkLogin.action")
public String validateLogin(
#ModelAttribute("loginDto") LoginDto loginDetails,
HttpServletRequest request) {
boolean validUser;
try {
validUser = userDao.validateLogin(loginDetails);
if (validUser) {
HttpSession session = request.getSession();
if (session.isNew()) {
logger.debug("New Session is Created");
System.out.println("Session id is" + session.getId());
} else {
logger.debug("Not a New Session");
System.out.println("Session Id" + session.getId());
}
//session.setMaxInactiveInterval(1000);
session.setAttribute("LoginData", loginDetails);
session.setAttribute("loggedUser",true);
return "home";
}
return "redirect:loginPage.action?message=Unable to Login invalid Id/Password";
} catch (DaoException e) {
logger.error("Problem in UserDao");
return "redirect:loginPage.action?message=Unable to Login invalid Id/Password";
} catch (Exception e) {
logger.error("problem validating User Login");
e.printStackTrace();
return "redirect:loginPage.action?message=Unable to Login invalid Id/Password";
}
}
this is how am setting data in my session and am able to retrieve that set attributes in view home to which on success it goes to, from home if i go to another view there am not able to get that data.
I wanted to know using anchor tag for navigating to another page clears the session data??????

Categories

Resources