How to bind the session to the User object using jersey - java

I am trying to create login function and I want to save in the session specific data to use in future requests of the user is it possible?
In the loginUser, first if is always false even if the user already logged
and same in the updatePassword .
I need to save the attribute from the function loginUserToSession. Any idea why it doesn't work ?
here is my code
Resource
#Path("/logIn")
#Singleton
public class UserResource extends baseResource<UserDao, UserEntity>
{
#Path("/authenticateUser")
#GET
#UnitOfWork
public String loginUser(#Context HttpServletRequest req #QueryParam("callback") String callback, #QueryParam("loginInfo") LoginInfo loginInfo) throws JsonProcessingException
{
if(SessionManager.isUserConnected(req))
{
return ResourceResponse.getResourceJsonString("null", callback, "true", ErrorMessageEnum.SUCCESS);
}
String userName = loginInfo.username;
String plainTextPassword = loginInfo.password;
UserEntity user = objectDao.logIn(userName, plainTextPassword);
if(user != null)
{
SessionManager.loginUserToSession(req, user.getUserId(), userName);
return ResourceResponse.getResourceJsonString(user.getUserStatus(), callback, "true", ErrorMessageEnum.SUCCESS);
}
return ResourceResponse.getResourceJsonString("null", callback, "false", ErrorMessageEnum.LOGIN_FAILED);
}
#Path("/updatePassword")
#GET
#UnitOfWork
public String updatePassword(#Context HttpServletRequest req, #QueryParam("callback") String callback, #QueryParam("oldPwd") String oldPwd, #QueryParam("newPwd") String newPwd) throws JsonProcessingException
{
if(SessionManager.isUserConnected(req))
{
short userId = SessionManager.getUserId(req);
ObjectDaoResponse res = objectDao.updatePassword(userId, oldPwd, newPwd);
return ResourceResponse.getResourceJsonString(res.getObjectJsonString(), callback, res.getSuccess(), res.getCode());
}
else
{
return ResourceResponse.getResourceFailResponseString(callback, ErrorMessageEnum.USER_NOT_CONNECTED);
}
}
}
SessionManager.java
public static void loginUserToSession(HttpServletRequest req, short userId, String userName)
{
if(req == null)
{
return;
}
HttpSession session = req.getSession(true);
session.setAttribute(ATTRIBUTE_USER_NAME, userName);
session.setAttribute(ATTRIBUTE_USER_ID, userId);
session.setAttribute(ATTRIBUTE_USER_CONNECTED, true);
}
public static boolean isUserConnected(HttpServletRequest req)
{
if(req == null)
{
return false;
}
HttpSession session = req.getSession(false);
if(session != null)
{
boolean userConnected = (boolean) session.getAttribute(ATTRIBUTE_USER_CONNECTED);
if(userConnected)
{
return userConnected;
}
System.out.Println("session.getAttribute(ATTRIBUTE_USER_CONNECTED)== null");
}
return false;
}

Please change into Resource like this:
public String loginUser(#Context HttpServletRequest req #QueryParam("callback") String callback, #QueryParam("loginInfo") LoginInfo loginInfo) throws JsonProcessingException
{
if(SessionManager.isUserConnected(req))
{
return ResourceResponse.getResourceJsonString("null", callback, "true", ErrorMessageEnum.SUCCESS);
}else{
String userName = loginInfo.username;
String plainTextPassword = loginInfo.password;
UserEntity user = objectDao.logIn(userName, plainTextPassword);
if(user != null)
{
SessionManager.loginUserToSession(req, user.getUserId(), userName);
return ResourceResponse.getResourceJsonString(user.getUserStatus(), callback, "true", ErrorMessageEnum.SUCCESS);
}
}
}
Above was the flow error , whatever i got, Now you have to setattribute into session scope then use this:
HttpSession session = request.getSession();
session.setAttribute("UserName", "Usename_Value");
Or for request Scope use this:
request.setAttribute("attributeName",yourStringVAlue);

It turns out that for some reason google postman don't send the HttpServletRequest as it should be. so jersey translate it like new user and create an empty new HttpServletRequest. Conclusion do not test your server side with Google's postman
when i try to send the request from my client it work fine.

Related

How to block your own notifications

I am trying to learn how to build a forum from an available source. However the problem I have is the function to reply to comments and answer questions. When I reply to my question or comment, notify me that "vkhacbao answered vkhacbao's question" (vkhacbao is the account I log into). How can I block or set the condition so that when I comment, it's not sent to myself. Please help me, I tried everything for 3 days but with no success. Thanks very much
Code:
CommentController.java
#Controller
public class CommentController {
#Resource
private UserMapper userMapper;
#Resource
private CommentMapper commentMapper;
#Resource
private QuestionMapper questionMapper;
#Resource
private NotificationMapper notificationMapper;
#ResponseBody
#RequestMapping(value = "/comment",method = RequestMethod.POST)
public Object post(#RequestBody CommentCreateDto commentCreateDto,
HttpServletRequest request){
//把User写进session
Cookie[] cookies = request.getCookies();
if (cookies == null) {
return "login";
}
User user = null;
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")) {
String token = cookie.getValue();
user = userMapper.findBytoken(token);
if (user != null) {
request.getSession().setAttribute("user", user);
//获取未读的消息数量
int unreadnum=notificationMapper.getunreadcount(user.getId());
request.getSession().setAttribute("unreadnum",unreadnum);
}
break;
}
}
//把评论插入数据库
Comment comment=new Comment();
comment.setParent_id(commentCreateDto.getParent_id());
comment.setContent(commentCreateDto.getContent());
comment.setType(commentCreateDto.getType());
comment.setCreatetime(System.currentTimeMillis());
comment.setCommentor(user.getId());
commentMapper.insert(comment);
if (commentCreateDto.getType()==2){
//把回复评论的通知插入数据库
Notification notification=new Notification();
notification.setNotifier(comment.getCommentor());
Comment comment2=commentMapper.getparentbyid(commentCreateDto.getParent_id());
notification.setReceiver(comment2.getCommentor());
notification.setOuterid(commentCreateDto.getParent_id());
notification.setType(notificationEnum.NOTIFICATION_COMMENT.getType());
notification.setCreatetime(System.currentTimeMillis());
notification.setStatus(NotificationStatusEnum.UNREAD.getStatus());
notificationMapper.inserts(notification);
//增加评论数
commentMapper.updatecommentcount(commentCreateDto.getParent_id());
}
else {
//把回复问题的通知插入数据库
Question question=questionMapper.getbyId(commentCreateDto.getParent_id());
Notification notification=new Notification();
notification.setNotifier(user.getId());
notification.setReceiver(question.getCreateid());
notification.setOuterid(commentCreateDto.getParent_id());
notification.setType(notificationEnum.NOTIFICATION_QUESTION.getType());
notification.setCreatetime(System.currentTimeMillis());
notification.setStatus(NotificationStatusEnum.UNREAD.getStatus());
notificationMapper.inserts(notification);
//增加问题回复量
questionMapper.updatecomment(commentCreateDto.getParent_id());
}
ResultDto resultDto=new ResultDto();
return resultDto.success();
}
#ResponseBody
#RequestMapping(value = "/comment/{id}",method = RequestMethod.GET)
public ResultDto<List<CommentDto>> comments(#PathVariable(name = "id") int id,
HttpServletRequest request){
//查找type=2,即是回复评论的评论
List<Comment> comments = commentMapper.getCommentByid(id,2);
List<CommentDto> commentDto=new ArrayList<>();
//找到User
Cookie[] cookies = request.getCookies();
User user = null;
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")) {
String token = cookie.getValue();
user = userMapper.findBytoken(token);
break;
}
}
//把二级评论和对应的User写进每个CommentDto集合中
for (Comment comment:comments){
CommentDto dto=new CommentDto();
BeanUtils.copyProperties(comment,dto);
dto.setUser(user);
commentDto.add(dto);
}
ResultDto resultDto=new ResultDto();
//返回数据给前端
return resultDto.success(commentDto);
}
}
NotificationController.java
#Controller
public class NotificationController {
#Resource
private NotificationMapper notificationMapper;
#Resource
private CommentMapper commentMapper;
#GetMapping("/notification/{action}")
public String notification(#PathVariable("action")int id,
HttpServletRequest request){
//将通知设置为已读
notificationMapper.updatestatus(id);
//获取type,检验是回复评论还是回复问题
int type=notificationMapper.gettypebyid(id);
int outerid=notificationMapper.getouteridbyid(id);
int questionid;
if(type== notificationEnum.NOTIFICATION_QUESTION.getType()){
questionid=outerid;
}else {
questionid=commentMapper.getparentidbyid(id);
}
return "redirect:/question/"+questionid;
}
}
QuestionController.java
#Controller
public class QuestionController {
#Resource
private QuestionService questionService;
#Resource
private UserMapper userMapper;
#Resource
private CommentService commentService;
#Resource
private NotificationMapper notificationMapper;
#GetMapping("/question/{id}")
public String question(#PathVariable(name = "id")int id,
Model model,
HttpServletRequest request){
//查找cookies,观察是否有token存在
Cookie[] cookies = request.getCookies();
if (cookies == null) {
return "login";
}
User user = null;
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")) {
String token = cookie.getValue();
user = userMapper.findBytoken(token);
if (user != null) {
request.getSession().setAttribute("user", user);
//获取未读的消息数量
int unreadnum=notificationMapper.getunreadcount(user.getId());
request.getSession().setAttribute("unreadnum",unreadnum);
}
break;
}
}
Questiondto questiondto=questionService.getbyid(id);
//增加阅读数
questionService.increaseview(id);
model.addAttribute("questionDto",questiondto);
//展示回复数据
List<CommentDto> comments=commentService.getByid(id);
model.addAttribute("comments",comments);
//相关问题
String[] tags=questiondto.getTag().split(",");
StringBuilder msg=new StringBuilder();
for (String tag:tags){
msg.append(tag);
msg.append("|");
}
String result=msg.substring(0,msg.length()-1);
List<Question> relativequestion =questionService.getbytag(id,result);
model.addAttribute("relativequestion",relativequestion);
return "question";
}
}
Assuming the owners of the original message and the commenter are in the CommentController class, it would be this section
if (commentCreateDto.getType()==2){
Comment comment2=commentMapper.getparentbyid(commentCreateDto.getParent_id());
if ( !comment2.getCommentor().equals(comment.getCommentor()) ) {
Notification notification=new Notification();
notification.setNotifier(comment.getCommentor());
notification.setReceiver(comment2.getCommentor());
notification.setOuterid(commentCreateDto.getParent_id());
notification.setType(notificationEnum.NOTIFICATION_COMMENT.getType());
notification.setCreatetime(System.currentTimeMillis());
notification.setStatus(NotificationStatusEnum.UNREAD.getStatus());
notificationMapper.inserts(notification);
commentMapper.updatecommentcount(commentCreateDto.getParent_id());
}
}
Unfortunately, if that doesn't work for you, you'll need to learn more about the language and the code to determine where to make the change.

Spring MVC Web Request and Android Request to Same Method

I have an spring mvc web application in which users login to session "session.setAttribute" classically. Whenever I need loggedin user data I use this data.
Now I want to add android app and what I want to learn do I have to add additional methods for each android request and send user data within it?
Or Is there away to make a request to same methods.
What is the consept for this kind of cloud apps? Do I have to write different methods for android requests? Because it is not possible session.getAttribute when wemake an android request, it returns null.
User user = userService.getByUserNameAndPassword(userName, password);
if (user != null) {
if (user.isActive()) {
Account account = new Account(user, request.getRemoteAddr());
HttpSession httpSession = request.getSession(true);
AccountRegistry.add(httpSession);
httpSession.setAttribute(Constant.ACCOUNT, account);
result.put(Constant.REF, Constant.SUCCESS);
}
public class Account {
private UserRightsHandler userRightsService = null;
private User user;
private String ipAddress;
private boolean admin;
public Account(User user, String ipAddress) {
this.user = user;
this.ipAddress = ipAddress;
userRightsService = new UserRightsHandler(user);
setAdmin(userRightsService.isAdmin());
}
public UserRightsHandler getUserRightsService() {
return userRightsService;
}
public User getUser() {
return this.user;
}
public String getIpAddress() {
return ipAddress;
}
public boolean isAdmin() {
return admin;
}
private void setAdmin(boolean admin) {
this.admin = admin;
}
}
public class AccountRegistry {
private static final Map<String, HttpSession> sessions = new HashMap<String, HttpSession>();
public static void add(HttpSession session) {
sessions.put(session.getId(), session);
}
public static void remove(HttpSession session) {
if (session != null) {
sessions.remove(session.getId());
session.setAttribute(Constant.ACCOUNT, null);
session.invalidate();
}
}
public static HttpSession getByHttpSessionID(String httpSessionID) {
Set<String> keys = sessions.keySet();
Iterator it = keys.iterator();
while (it.hasNext()) {
String sID = (String) it.next();
HttpSession session = sessions.get(sID);
if (sID.equals(httpSessionID)) {
return session;
}
}
return null;
}
public static void removeByHttpSessionID(String httpSessionID) {
HttpSession session = getByHttpSessionID(httpSessionID);
remove(session);
}
public static Account getCurrentAccount() {
HttpServletRequest request = ContextFilter.getCurrentInstance().getRequest();
HttpSession session = request.getSession();
return (Account) session.getAttribute(Constant.ACCOUNT);
}
}
#RequestMapping(value = "/changeStatus", method = RequestMethod.POST)
public #ResponseBody
String changeStatus(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
User editor = AccountRegistry.getCurrentAccount().getUser();
}
You can ask user send their user and password at the start of Android app via custom authenticate request like /appLogin then if it is correct creditentals you can return a key to user (to app) and store it to some variable during app run. Then when user want to do something send a request to server you can send it to a function with mapping like /appExampleService then you can check at that function this key and device valid depending on how you handle custom login process then this function call existing function that is used for web browsers that have mapping /exampleService. For example;
#JsonSerialize
#RequestMapping("/appExampleService")
public int someServiceForAppClient(
#RequestParam(value = "key", required = true) String apikey,
#RequestParam(value = "param", required = true) String someParam{
String name=userDAO.getUsernameFromApiKey(apikey);
return someService(someParam, name);
}
#JsonSerialize
#RequestMapping("/exampleService")
public int someServiceForWebClient(
#RequestParam(value = "param", required = true) String someParam) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName();
return someService(someParam, name);
}
public int someService(String someParam,String name){
return doBusiness(someParam, name);
}
userDAO is just something I created for to get info of user with given key. And there is a service for App login as well which return that key to user when he started the app send his username and pass

Play Framework: Using JPA entityManager in Interceptor Action class

I am using #With(Action.class) annotation to intercept the calls to specific controller/actions. I am trying to retrieve the session from database on in the interceptor function; however the JPA helper class is not available in the Action.class interceptor method "call".
Can someone please guide on how to retrieve database entities in the interceptor functions?
Thanks.
Interceptor class:
public class SecuredAction extends Simple {
public SecuredAction() {
// TODO Auto-generated constructor stub
}
#Override
public Promise<Result> call(Context ctx) throws Throwable {
// check isContactVerified/isEmailVerified
String sid = getSidFromCookie(ctx);
if (sid != null) {
Session appSession = (Session) JPA.em().createNamedQuery("Session.findBySessionId").getSingleResult();
User user = appSession.getUserId();
if (user != null) {
ctx.args.put("user", user);
return delegate.call(ctx);
}
}
Result unauthorized = Results.unauthorized("Invalid Session");
return F.Promise.pure(unauthorized);
}
private String getSidFromCookie(Http.Context ctx) {
return ctx.session().get(AppConstants.COOKIE_USER_SESSIONID);
}
}
Error:
[RuntimeException: No EntityManager bound to this thread. Try to annotate your action method with #play.db.jpa.Transactional]
Wrap body of you action with JPA.withTransaction:
return JPA.withTransaction(
"default",
false, () -> {
String sid = getSidFromCookie(ctx);
if (sid != null) {
Session appSession = (Session) JPA.em().createNamedQuery("Session.findBySessionId").getSingleResult();
User user = appSession.getUserId();
if (user != null) {
ctx.args.put("user", user);
return delegate.call(ctx);
}
}
Result unauthorized = Results.unauthorized("Invalid Session");
return F.Promise.pure(unauthorized);
}
);
And do not annotate method with #Transactional if you annotated it with #With(SecuredAction.class).

Please ensure that at least one realm can authenticate these tokens

So I have set up my shiro to have two Realms. A Username and Password Realm, using the standard UsernamePasswordToken. I have also set up a Custom Bearer Authentication Token that works off a token passed in from the user.
If i just use my passwordValidatorRealm it works find, if no user is found throws unknown account, if password doesn’t match throws incorrect credentials, perfect. But as soon as i put in my tokenValidatorRealm it throws a
org.apache.shiro.authc.AuthenticationException: Authentication token of type [class org.apache.shiro.authc.UsernamePasswordToken] could not be authenticated by any configured realms.
In this instance my tokenValidatorRealm returns null as no token was provided, so it moves on to the passwordValidatorRealm and just breaks.
Any ideas why introducing a second Realm will cause my working passwordValidatorRealm to break?
Have tried with different authentication strategies, and no luck there.
Using shiro 1.2.2
EDIT
I have two implementations, one for password and one for token
Password:
public class PasswordAuthorizingRealm extends AuthenticatingRealm {
#Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
if (authenticationToken instanceof UsernamePasswordToken) {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
String username = usernamePasswordToken.getUsername();
char[] password = usernamePasswordToken.getPassword();
if (username == null) {
throw new AccountException("Null usernames are not allowed by this realm!");
}
//Null password is invalid
if (password == null) {
throw new AccountException("Null passwords are not allowed by this realm!");
}
UserService userService = new UserServiceImpl();
User user = userService.getUserByUsername(username);
if (user == null) {
throw new UnknownAccountException("Could not authenticate with given credentials");
}
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, user.getPassword(), "passwordValidatorRealm");
return simpleAuthenticationInfo;
} else {
return null;
}
}
}
and Bearer Token
public class TokenAuthorizingRealm extends AuthorizingRealm {
#Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
if (authenticationToken instanceof BearerAuthenticationToken) {
BearerAuthenticationToken bearerAuthenticationToken = (BearerAuthenticationToken) authenticationToken;
String username = "" + bearerAuthenticationToken.getPrincipal();
User user = userService.getUserByUsername(username);
//User with such username has not found
if (user == null) {
throw new UnknownAccountException("Could not authenticate with given credentials");
}
BearerAuthenticationInfo bearerAuthenticationInfo = new BearerAuthenticationInfo(user);
return bearerAuthenticationInfo;
}
}
Shiro config
[main]
hashService = org.apache.shiro.crypto.hash.DefaultHashService
hashService.hashIterations = 500000
hashService.hashAlgorithmName = SHA-256
hashService.generatePublicSalt = true
hashService.privateSalt = ****
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordService.hashService = $hashService
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordMatcher.passwordService = $passwordService
authc = my.BearerTokenAuthenticatingFilter
tokenValidatorRealm = my.TokenAuthorizingRealm
passwordValidatorRealm = my.PasswordAuthorizingRealm
passwordValidatorRealm.credentialsMatcher = $passwordMatcher
securityManager.realms = $tokenValidatorRealm,$passwordValidatorRealm
These have been stripped out a bit, removed logging and other unnecessary code
The BearerTokenAuthenticatingFilter, just basically checks if a token has been supplied in the header if has
private void loginUser(ServletRequest request, ServletResponse response) throws Exception {
BearerAuthenticationToken token = (BearerAuthenticationToken) createToken(request, response);
if (token == null) {
String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken "
+ "must be created in order to execute a login attempt.";
throw new IllegalStateException(msg);
}
try {
Subject subject = getSubject(request, response);
subject.login(token);
onLoginSuccess(token, subject, request, response);
} catch (AuthenticationException e) {
HttpServletResponse httpResponse = WebUtils.toHttp(response);
httpResponse.sendRedirect("login");
}
}
BearerAuthenticationInfo class
public class BearerAuthenticationInfo implements AuthenticationInfo {
private final PrincipalCollection principalCollection;
private final User user;
public BearerAuthenticationInfo(User user) {
this.user = user;
this.principalCollection = buildPrincipalCollection(user);
}
public PrincipalCollection getPrincipals() {
return principalCollection;
}
public Object getCredentials() {
return user.getUsername();
}
private PrincipalCollection buildPrincipalCollection(User user) {
Collection<String> principals = new ArrayList<String>();
principals.add(user.getUsername());
return new SimplePrincipalCollection(principals, "tokenValidatorRealm");
}
}
Looks like it is expected behavior.
If you look at the javadoc for ModularRealmAuthenticator:
* #throws AuthenticationException if the user could not be authenticated or the user is denied authentication
* for the given principal and credentials.
*/
protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken) throws AuthenticationException {
If you are having problems with the exception, you might need to change the code that calls the authentication to expect this exception.
Left for other searches:
You might have a missing supports method in your TokenAuthorizingRealm class.
Something like
#Override
public boolean supports(AuthenticationToken token) {
return token instanceof BearerAuthenticationToken;
}
should be present.
This discussion help me solve a similar problem. I wanted to authenticate a user by the application itself, not using any Shiro default implementation. To do that we must subclass AuthenticatingRealm, override doGetAuthenticationInfo and declare this realm as the validation one.
public class PasswordAuthorizingRealm extends AuthenticatingRealm {
#Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
In Shiro.ini:
passwordValidatorRealm = my.PasswordAuthorizingRealm

session does not invalidates

I'm trying to write a filter, which checks if user is logged in, and in case is not redirect him to login page. previously I had filter which actually did nothing -_- here it is, and with this filter everythig works ok, and session invalidates:
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpSession session = request.getSession();
if (session == null || session.getAttribute("UserName") == null) {
String command = request.getParameter("command");
request.setAttribute("command", "login");
// String page = ConfigurationManager.getInstance().getProperty(
// ConfigurationManager.LOGIN_PAGE_PATH);
} else {
String username = (String) session.getAttribute("UserName");
UserRole role;
try {
role = UserDAOImpl.getUserRole(username);
session.setAttribute("role", role);
} catch (DAOTechnicException e) {
logger.error(e);
} catch (DAOLogicException e) {
logger.error(e);
}
}
chain.doFilter(req, res);
}
and when I invalidate session then it goes to (if session == null) block, and everything is ok.
but now I have another filter, here it is :
public class UserCheckFilter implements Filter {
static class FilteredRequest extends HttpServletRequestWrapper {
public FilteredRequest(ServletRequest request) {
super((HttpServletRequest) request);
}
public String getParameter(String paramName) {
String value = super.getParameter(paramName);
if(value!=null){
if (value.equals("login")) {
return value;
}
HttpSession session = super.getSession();
if (session == null || session.getAttribute("UserName") == null) {
value = "login";
}
}
return value;
}
}
/**
* Checks if user logged in and if not redirects to login page
*/
#Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("UserName") == null) {
if(request.getParameter("command")!=null){
String command = request.getParameter("command");
if(!command.equals("login")){
FilteredRequest filtrequest = new FilteredRequest(request);
String filteredvalue = filtrequest.getParameter("command");
chain.doFilter(filtrequest, res);
}else{
chain.doFilter(req, res);
}
}else{
chain.doFilter(req, res);
}
} else {
String username = (String) session.getAttribute("UserName");
UserRole role;
chain.doFilter(req, res);
try {
role = UserDAOImpl.getUserRole(username);
session.setAttribute("role", role);
} catch (DAOTechnicException e) {
logger.error(e);
} catch (DAOLogicException e) {
logger.error(e);
}
}
}
in which I wrap getParameter method and check if not logged in user is trying to go to user or admin pages. But when I invalidate session, it does not invalidates, i.e. all parameters are staying the same, and then in the filter where it checks if session != null, it's not null, and in line session.setAttribute("role", role); I get exception "session is already invalidated"
here's the method where i invalidate session :
if(request.getSession(false)!=null){
request.getSession().invalidate();
}
String page = ConfigurationManager.getInstance().getProperty(
ConfigurationManager.LOGIN_PAGE_PATH);
return page;
and in servlet U use
RequestDispatcher dispatcher = getServletContext()
.getRequestDispatcher(page);
dispatcher.forward(request, response);
and btw such things with invalidating session occurs only with second filter
p.s. sorry for probably stupid question, but I really don't know what's wrong,
so any suggestions would be appreciated.
I think this is because you're always calling chain.doFilter().
Per Oracle's docs...
A typical implementation of this method would follow the following
pattern:-
Examine the request
Optionally wrap the request object with a custom implementation to filter content or headers for input filtering
Optionally wrap the response object with a custom implementation to filter content or headers for output filtering
a) Either invoke the next entity in the chain using the FilterChain object (chain.doFilter()),
b) or not pass on the request/response pair to the next entity in the filter chain to block the request processing
Directly set headers on the response after invocation of the next entity in the filter chain.
In step 4, you probably want to do (b) - that is, instead of passing the request to the next filter in the chain, return the result to the user. I mean, it's an invalid session, so why bother trying to perform additional processing?

Categories