java - 当其他人登录时(从另一台计算机)用户记录的更改

标签 java tomcat servlet-filters

我真的需要任何帮助。 我有一个在 tomcat 6 上运行 PrimeFaces 的 JSF 应用程序。

我以为我已经完成了应用程序,但是在测试时,我发现了一个巨大的问题。 当我以计算机 1 中的用户(例如“admin”)登录应用程序,然后以计算机 2 中的另一个用户(例如“peter”)登录时,计算机 1 现在无法访问允许用户 admin 访问的页面。如果我稍后以管理员用户再次登录计算机 1,现在在计算机 2 中,peter 可以访问允许管理员访问的所有页面。

这就像我有一个 session 用于所有 tomcat session 或类似的东西。

我搜索了 throw 我的应用程序,但没有找到 @applicationScoped,我有所有 @sessionScoped bean。

我不知道该怎么办。请帮忙。

我在这里附上我的自定义过滤器:

public abstract class AbstractLoginFilter implements javax.servlet.Filter {

protected ServletContext servletContext;

@Override
public void init(FilterConfig filterConfig) {
    servletContext = filterConfig.getServletContext();
}

@Override
public void doFilter(
        ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse resp = (HttpServletResponse) response;
    String pageReq = req.getRequestURL().toString();        
    HttpSession session = req.getSession(false);

    String[] temp = pageReq.split("/faces", 2);

    String url = temp[1];
    resp.setCharacterEncoding("UTF-8");
    req.setCharacterEncoding("UTF-8");

    if ("/login.xhtml".equals(url)) { 

        continueExecution(chain, request, response);
    } else {

        if (session == null) {

            //session timeout check.
            if (req.getRequestedSessionId() != null && !req.isRequestedSessionIdValid()) {

                System.out.println("La sesión ha expirado");
                session = req.getSession(true);

                //si es un ajax
                if ("partial/ajax".equals(req.getHeader("Faces-Request"))) {
                    resp.setContentType("text/xml");
                    resp.getWriter().append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", "/Autorack/faces/login.xhtml");
                } else {
                    resp.sendRedirect("/Autorack/faces/login.xhtml");
                }
            }
        } else {
            if (Global.getLoggedUser() == null) {
                resp.sendRedirect("/Autorack/faces/login.xhtml");
            } else {
                if (isPublicPage(url) || isAuth(url)) {
                    continueExecution(chain, request, response);
                } else {

                    resp.sendRedirect("/Autorack/faces/noAutorizacion.xhtml");
                }
            }
        }
    }
}

private void continueExecution(FilterChain chain, ServletRequest request, ServletResponse response) throws ServletException, IOException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse resp = (HttpServletResponse) response;

    //when i make a BACK
    if (!req.getRequestURI().startsWith(req.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
        resp.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        resp.setHeader("Pragma", "no-cache"); // HTTP 1.0.
        resp.setDateHeader("Expires", 0); // Proxies.
    }
    chain.doFilter(request, response);
}

private boolean isPublicPage(String url) {
    List<String> urlsPublicas = new ArrayList<String>();
    urlsPublicas.add("/inicio.xhtml");
    urlsPublicas.add("/noAutorizacion.xhtml");
    urlsPublicas.add("/usuario/CambioPassword.xhtml");

    return urlsPublicas.contains(url);


}

@Override
public void destroy() {
}

/**
 * logic to accept or reject access to the page, check log in status
 * @return true when authentication is deemed valid
 */
protected abstract boolean isAuth(String reqPage);
}

这是我的 web.xml

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
    <description>Customizable Filter</description>
    <filter-name>customFilter</filter-name>
    <filter-class>com.oriuken.autorack.security.LoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>customFilter</filter-name>
    <url-pattern>*.xhtml</url-pattern>                
</filter-mapping>
<error-page>
    <error-code>401</error-code>
    <location>/noAutorizacion.xhtml?faces-redirect=true</location>
</error-page>
<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Production</param-value>
</context-param>
<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
    <session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
    <welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>casablanca</param-value>
</context-param>
<context-param>
    <param-name>primefaces.PUSH_SERVER_URL</param-name>
    <param-value>ws://localhost:8088</param-value>
</context-param>
<context-param>
<param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
<param-value>true</param-value>

感谢任何线索!

最佳答案

而不是使用

Global.getLoggedUser() 

了解我们为实现相同目的而实现的 ThreadLocal

这是一些可能对您有所帮助的代码片段...

public class UserHolder {

private static ThreadLocal<User> userThreadLocal = new ThreadLocal<User>();

private static Log log = LogFactory.getLog(UserHolder.class);

public UserHolder(User user) {
    if (userThreadLocal.get() == null) {
        userThreadLocal.set(user);
        log.debug("User bound to thread " + user.getUsername()); 
    } else {
        log.debug("User already bound to thread " + user.getUsername());
    }
}

public static User getUser() {
    return userThreadLocal.get();
}

public static void setUser(User user) {
        userThreadLocal.set(user);
}

public static void remove() {
    userThreadLocal.remove();
}
}

在应用程序过滤器后身份验证中,我们通过从 session 变量中读取它来在 UserHolder 中设置用户,例如:

 new UserHolder((User) session.getAttribute("USER_ATTR_KEY"));
 // deliver request to next filter
 chain.doFilter(request, response);

关于java - 当其他人登录时(从另一台计算机)用户记录的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11979942/

相关文章:

Java 并以编程方式将 csv 导入 SQLite3 表

jsp - 你能把一个 WebFilter 打包成一个库吗

servlets - 如何将信息从 Servlet 过滤器传递到 ReSTLet ServerResource 子类?

java - 使用 ASP .NET 中的 Servlet

java - 检查图像是否为灰度的可靠方法

java - 为什么格式化日期是上个世纪

tomcat - 部署solr和tomcat同端口

linux - Ant Tomcat : Failed to create task or type "list"

apache - Tomcat 多个本地主机实例

spring-boot - 为单元测试禁用 servlet 过滤器