I'm using Java EE (EJB, JPA, JSF) and JBoss. How can I check online users? Of course, I have User entity. And user can login and logout. I thought we can check the session that created when a user login. But when that session times out, how do we know?
You can use HttpSessionListener, it receives notification when an HTTP session is activated or is about to be deactivated.
In order to receive these notification events, the implementation class must be either declared in the deployment descriptor of the web application or annotated with WebListener.
There are two methods declared in the HttpSessionListener interface which must be implemented by the servlet programmer to perform some action.
public void sessionCreated(HttpSessionEvent e) : is invoked when
session object is created.
public void sessionDestroyed(ServletContextEvent e) : is invoked when session is invalidated.
Here you can get an tutorial for implementation.
Related
I have a springboot application where with authentication available in SecurityContext post login. Any call from Rest Controller to persist any entity, getCurrentAuditor() method is called which returns the current principle which is used for auto updating the created date column.
I created an schedular using spring "awaitility" dependency. However, this schedular calls an update on a entity. When update is called and spring authentication is checked, it comes as null, even though i have logged in from front end. From front end i am able to persist other entities and gets the authentication object as well.
As per my understanding, this might be happening because the schedular starts as soon as Springboot kicks in and making save request independently. If that understanding is correct, how should i resolve this?
If the Scheduler can use a "system" user for update the entity, you can do something like the following and in the scheduler code perform the authentication:
public void authenticate() {
Authentication auth = authenticationManager.authenticate(getBatch());
SecurityContext sc = SecurityContextHolder.getContext();
sc.setAuthentication(auth);
}
public UsernamePasswordAuthenticationToken getBatch() {
return UsernamePasswordAuthenticationTokenBuilder.anUsernamePasswordAuthenticationToken()
.withCredentials(batchProperties.getPassword()).withUserCode(batchProperties.getUser()).withUserDto(
userDtoFactory.getBatch()).build();
}
I'm implementing some REST services in Spring and need to reject, in some cases, a successful login of a user.
I have implemented my UserDetailsService and programmed the loadUserByUsername(String username) method, but, when a user gets correctly authenticated, I need to do another validation and, if it fails, reject the access.
To do so I have implemented a listener to detect correct authentications:
#Component
public class LoginSuccessListener implements ApplicationListener{
#Autowired
LicenseControlService licenseControlService;
#Override
public void onApplicationEvent(InteractiveAuthenticationSuccessEvent e){
User user = (User)e.getAuthentication().getPrincipal();
//Here I want to reject the access because of whatever logic
}
I need to be sure to apply the logic which might reject the access when the user gets correctly authorized, that's why I need to put the logic when I receive this event.
Is there any way to do that?
Im posting the solution I have adopted in case someone needs the same behaviour:
What I did was, at the class which implements the UserDetailsService, when returning the User class, instantiate it with a false at the enabled property... that returns a 401 to the requester.
I also implemented a CustomAuthenticationEntryPoint which extends BasicAuthenticationEntryPoint, and with an overriden comence method. That method is called whenever Spring is returning an authentication error, so, in this method, I can query the type of the AuthenticationException and decide and modify the returned status according to it.
We have an application with 3 different user roles as User, Author & Admin. Each access role is having different set of menus and screens.
Issue is even though Menu item is hidden if we capture the admin URL and past it in user login it is opening the page. All action on the page will not work but still we are planning to restrict the page opening as well.
Only way I could see how we can handle is write a condition in each action to validate the access before opening the page. But with this approach we should touch many files, is there any best way to handle this situation.
Our application is written using Spring MVC framework.
Thanks.
You asked:
But with this approach we should touch many files, is there any best
way to handle this situation.
From Spring MVC HandlerInterceptor javadoc:
"Applications can register any number of existing or custom
interceptors for certain groups of handlers, to add common
preprocessing behavior without needing to modify each handler
implementation."
What you may do:
Write a custom HandlerInterceptor which should extend
HandlerInterceptorAdapter.
Override the boolean preHandle() method. This method is invoked just before the handler is invoked. So you can check access of logged in user (maybe from session). You can write a custom response from within this method.
Register the interceptor in your dispatcher-servlet.xml.
For example:
public class AuthInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
String uri = request.getRequestURI();
User user = (User) request.getSession().getAttribute("foo"); //for example
if (...) { //check access to this uri, if access fails
response.sendRedirect("/to/some/url");
return false;
}
return true;
}
}
And register this HandlerInterceptor to dispatcher-servlet.xml:
<mvc:interceptors>
<bean class="your.package.AuthInterceptor"/>
</mvc:interceptors>
You can configure this interceptor to be more url-specific. See Spring Reference and Spring javadoc.
I am working on a weam web application where the once the user logs in, the main (or landing) page calls 4 stateful session beans. So once the user logs in, there will be atleast 4 threads of stateful session beans created. The page also has a logout button. The logout component in the xhtml calls a POJO which has a logout method.
In the logout method, the following statement is executed:
Session.instance().invalidate();
Now the question is, will the 4 threads/instances of the stateful session beans which are created when the user logs in will be destroyed or not.
I am running this application on JBOSS 4.2.3, Seam 2.2.1 Final
I am using JOSSO for authentication.
Yes, they're all part of the same session. You're actually creating session scoped beans, not separate sessions.
Easy enough to check though. Create a method in each of the session beans and annotate them with #Destroy, when the annotated bean is destroyed, it will call this method.
#Destroy
public void callMeWhenIDie(){
log.debug("I'm melting, I'm melting" + this.someDefiningCharacteristic);
}
I'm using Spring 3.1.1.Release, Security 3.1.0.Release.
I've added login/logout to my web app, however a session scoped bean is not functioning the way it was. The bean is used to connect to a CMS called CMSConnector.
To authenticate users, I implemented an AuthenticationProvider, and in the authenticate() call, I get the session-scoped CMSConnector and call the CMSConnector.login(). If the CMS login fails, it fails the login.
THE PROBLEM -
If the login is success, #predestroy logout() is called immediately after the successful login. I then found it was the SessionFixationProtectionStrategy is invoking the invalidate the previous session and assign it a new session.
session.invalidate();
session = request.getSession(true); // we now have a new session
The invalidate() is calling the #predestroy method on the session-scoped bean.
So I have temporarily removed the the #predestroy annotation leaving the connection not closed. (VERY BAD PRACTICE.)
What is a work around to resolve the issue?
I tried to create a #PostConstruct and put the login process there, but the #PostConstruct doesn't get called when request.getSession(true) is called.
Thanks!
Jason
I think its not the SessionFixationProtectionStrategy but the ConcurrentSessionControlStrategy.
Set max-sessions="-1" for this code snippet
I did not solve my original question, but I implemented a workaround - expire session in the session expire object instead of attached with #predestroy.