I would like to get the username from within HttpSessionListener.sessionCreated(). When I say username, I mean specifically that name that is returned by HttpServletRequest.getRemoteUser().
Obviously, there must have been a HttpServletRequest object that caused the session to be created (and hence the sessionCreated() call). But how do I access it from within sessionCreated()? The HttpSessionEvent object passed into sessionCreated() appears to provide no way to get at the HttpServletRequest object that caused the session to be created.
The HttpSessionListener does not have access to the HttpServletRequest object because it is invoked when no request has been madeāto notify of session destruction or creation.
So, a Filter would be better places where you can add username = request.getRemoteUsr() into session.
Example - Filter Code
String username = request.getRemoteUsr() ;
session.setAttribute("username",username);
and then retrive this username in sessionCreated method as
String username = (String)session.getAttribute("username");
i hope you will get the same username of the same request which has created this session in HttpSessionListener sessionCreated() method.
// set
session.setAttribute("username", request.getRemoteUser();
// get
String un = (String) session.getAttribute("username");
You could use a HttpSessionAttributeListener:
public class UsernameHttpSessionAttributeListener implements HttpSessionAttributeListener {
#Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
if (httpSessionBindingEvent.getName().equals("username")) {
// do something
}
}
...
}
Of course, you need to set the attribute username in the HTTP session anywhere, for instance in a servlet filter.
Related
So, I am working on creating a simple chat app. I'm not using spring security.
So, in front end, the user enters their name which is handled by this controller.
#PostMapping("/addUser")
public User addUser(#RequestBody String name, HttpServletRequest request) {
String session = (String) request.getSession().getAttribute("sessionId");
System.out.println("Session id is " + session);
User newUser = new User(name, session);
userService.addUser(newUser);
System.out.println(newUser);
return newUser;
}
I'm using pre handler method handler interceptor to generate session id for the user. Below is the code:
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("Its working");
// TODO Auto-generated method stub
if(request instanceof HttpServletRequest) {
HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpSession session = servletRequest.getSession();
session.setAttribute("sessionId", session.getId());
System.out.println("Connected with session id : " + session.getAttribute("sessionId"));
}
return true;
}
So, I want to make sure that whenever users are inactive for cetain time, I want to end the session for that user and also remove that user from the arraylist of user where I have kept all the users who register by entering their name (in the front end).
Is it possible to achieve without sprin security or do I have to learn spring security to implement it.
I did try using task scheduler but then I found out in some article that its impossible to call HttpSession there.
You can set the session life (time it can be inactive before being killed) with server.servlet.session.timeout=30m
You can take the user out of your list by implementing a HttpSessionListener.sessionDestroyed - spring-boot-session-listener
if you use WebSocket, You can use heartbeat for your session, on the other hand, if you use rest then you should keep the session in memory(redis, hazelcast, or in-memory (singleton object) like map<key, session>,
(keep in mind, the client should send a disconnect request or you should control it in the backend)
I was having some problem when trying to use #SessionAttribute in Spring MVC Controller. Basically what I am trying to do is, in my API, I want to retrieve from the session, if it contains data, fetch it out, then remove the session itself. Here is my controller class:
#SessionAttributes({WebKeys.SEARCH_RESULT_LIST_THREE})
public class ALController {
#RequestMapping(value = "/search.do", method = { RequestMethod.POST })
public String doSearchList(Model model, #ModelAttribute("attendanceTO") AttendanceTO attendanceSearchForm, #SessionAttribute(WebKeys.SEARCH_RESULT_LIST_THREE) String[] selectedRecords) {
// removed code
attendanceSearchForm.setSelectedRecords(null);
// checking from session
if(selectedRecords != null && selectedRecords.length > 0){
attendanceSearchForm.setSelectedRecords(selectedRecords);
}
model.addAttribute("selectedRecords", selectedRecords);
// remove session
model.addAttribute(WebKeys.SEARCH_RESULT_LIST_THREE, null);
}
}
At this point of time, the session is not existed yet. I only set up the session when user submit form. I am getting this error messages:
Missing session attribute 'key.searchResultList.three' of type String[]
Any ideas on how to resolve this? Thanks!
U should add a required parameter to the #SessionAttribute annotation and set its value to false,meaning it's not necessary,like
#SessionAttribute(name=WebKeys.SEARCH_RESULT_LIST_THREE,required=false)
My objective is to pass model attributes from controller to JSP page during a redirect and avoid the attribute being displayed in URL. The source code below is validating login from datastore using java data objects.
Controller:
#Controller
public class LoginController {
int count;
PersistenceManager pm = PMF.get().getPersistenceManager();
//Instance of data class
User user;
ModelAndView modelAndView=new ModelAndView();
#RequestMapping(value="/Login",method = RequestMethod.POST)
public ModelAndView loginValidate(HttpServletRequest req){
//Getting login values
String uname=req.getParameter("nameLogin");
String pswd1=req.getParameter("pswdLogin");
count=0;
user=new User();
//Generating Query
Query q = pm.newQuery(User.class);
q.setFilter("userName == userNameParam");
q.declareParameters("String userNameParam");
try{
List<User> results = (List<User>) q.execute(uname);
for (User u: results) {
String userName=u.getUserName();
if(userName.equals(uname)){
System.out.println(u.getPassword());
if(u.getPassword().equals(pswd1)){
count=count+1;
modelAndView.setViewName("redirect:welcome");
modelAndView.addObject("USERNAME",uname);
return modelAndView;
}
//rest of the logic
}
JSP:
<h1>Welcome ${USERNAME} </h1>
My current URL is /welcome?USERNAME=robin
My goal is to display it as /welcome
Also, my page is supposed to display "Welcome robin" whereas it displays only Welcome.
RedirectAttributes only work with RedirectView, please follow the same
#RequestMapping(value="/Login",method = RequestMethod.POST)
public RedirectView loginValidate(HttpServletRequest req, RedirectAttributes redir){
...
redirectView= new RedirectView("/foo",true);
redir.addFlashAttribute("USERNAME",uname);
return redirectView;
}
Those flash attributes are passed via the session (and are destroyed immediately after being used - see Spring Reference Manual for details). This has two interests :
they are not visible in URL
you are not restricted to String, but may pass arbitrary objects.
You need to be careful here because I think what are you trying to do is not supported for a good reason. The "redirect" directive will issue a GET request to your controller. The GET request should only retrieve existing state using request parameters, this is the method contract. That GET request should not rely on a previous interaction or on any object stored some where in the session as a result of it. GET request is designed to retrieve existing (persisted) state. Your original (POST) request should have persisted everything you need for you GET request to retrieve a state.
RedirectAttributes are not designed to support you in this case, and even if you managed to correctly use it it will only work once and then they will be destroyed. If you then refresh the browser you will get an application error because it cannot find your attributes anymore.
I have an interceptor that implements PreProcessInterceptor.
I need to get the HttpSession object in the preProcess method, so I'm using:
#Context
private HttpServletRequest httpRequest;
and then:
httpRequest.getSession();
to get the HttpSession object.
At first I thought everything was working fine, but then I realized that the httpRequest.getSession() was returning a new HttpSession object on every request.
I need to set some session attributes on the user first request and then use those attributes on futher requests. The attributes are being set all right, I can even access those attributes down along that same request stack. However, as I am getting a new Session on every new request, I am not able to access those attributes.
Do I need to send something from the client side do my REST services, like a token or something?
Here is a more complete view of my Interceptor
#Provider
#ServerInterceptor
#SecurityPrecedence
public class SecurityInterceptor implements PreProcessInterceptor, AcceptedByMethod {
...
#Context
private HttpServletRequest httpRequest;
#Override
public boolean accept(Class classe, Method metodo) {
return metodo.getAnnotation(PermitAll.class) == null;
}
...
#Override
public ServerResponse preProcess(HttpRequest request, ResourceMethod resourceMethod) {
HttpSession httpSession = httpRequest.getSession();
// Set attributes on httpSession
...
return null;
}
}
Session is tried to the concept of HTTP Cookies.
The processing of the First HTTP request would have detected that there is no current Session and created a new one. The Session ID would've then been populated as a Cookie (Http Response Header) whenever the Response was returned to the Client.
If your Second HTTP Request had a Request Header for that same Cookie, then httpSession wouldn't be created new.
So, whenever you are sending requests to the Server, check if there exists a Cookie in the Server and send that cookie with each request.
I have a login method in a GWT RPC Servlet, which gets a user from the session context and therefore determins, if the user is logged in or not. I want to port this method to the request factory approach (to get a proxy entity instead of a DTO).
But where can i place it? I can't place it in the Entity because there i don't have the session context. Whats the right approach here?
My RPC method currently looks like this:
#Override
public UserDTO isLoggedIn() {
// TODO Auto-generated method stub
HttpSession session = getThreadLocalRequest().getSession();
String userName = (String)session.getAttribute("userName");
if(userName !=null){
return new UserDTO(userName);
}
return null;
}
RequestFactory also provides methods for accessing the request and servlet context
HttpSession session = com.google.web.bindery.requestfactory.server.RequestFactoryServlet.getThreadLocalRequest().getSession();
Documentation can be found here:
http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/web/bindery/requestfactory/server/RequestFactoryServlet.html#getThreadLocalRequest()