扩展ValveBase在Tomcat中总是返回null request.getRemoteUser()

时间:2019-02-02 22:36:27

标签: java tomcat logging tomcat-valve

我已经在Tomcat 8.0.51和9.0.14中对此进行了测试,结果相同。运行在Ubuntu Linux 16.04。

此示例代码仅将所有请求记录到控制台(或catalina.out)。主要问题是request.getRemoteUser()始终返回null-即使用户已通过身份验证。

我注意到AccessLogValveJDBCAccessLogValve阀门在用户通过身份验证后正确返回了登录名/用户名。我通过在access_log行中显示我的Valve记录到标准控制台日志中的相同代码行来显示此内容。

我的LoginValve是否需要扩展或实现一个类,以便在验证用户身份后返回登录名/用户?我还尝试了对request.getUserPrincipal()的调用,它也总是返回null。

非常感谢ValveBase被阻止但可用于AccessLogs的任何帮助。

package org.apache.catalina.connector;

import java.io.IOException;
import java.time.LocalDateTime;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;

public class LoginValve extends ValveBase {
    public void invoke(Request request, Response response) throws IOException, ServletException {
        String reqlogin=request.getRemoteUser();
        String method=request.getMethod();
        String requestURI=request.getRequestURI();
        HttpSession session = request.getRequest().getSession();
        String sid=session.getId();
        String user_id = (String) session.getAttribute("UserID");
        String sesslogin=(String) session.getAttribute("login");  // put in session by app code
        LocalDateTime now=LocalDateTime.now();
        System.out.println("LoginValve: "+now+" sid: "+sid+" UserID: "+user_id+" method: "+method+" requestURI: "+requestURI+" reqlogin: "+reqlogin+" sesslogin: "+sesslogin);

        getNext().invoke(request, response);
    }
}

如果LoginValve的输出是下面。请注意,由呼叫提供给场request.getRemoteUser() reqlogin sesslogin 字段由应用填充到会话中,与getRemoteUser()调用无关。

LoginValve: 2019-02-02T15:58:06.034 sid: 79D54B40DB8131E2A74375A67CE72ECD UserID: 3776559 method: GET requestURI: /app/auth/logoff.jsp reqlogin: null sesslogin: joe_user
LoginValve: 2019-02-02T15:58:06.050 sid: 41D1AD1DBBE5FA1D6EE4CB7A350D7DD6 UserID: null method: GET requestURI: /app/index.jsp reqlogin: null sesslogin: null
LoginValve: 2019-02-02T15:58:07.958 sid: 41D1AD1DBBE5FA1D6EE4CB7A350D7DD6 UserID: null method: GET requestURI: /app/user/index.jsp reqlogin: null sesslogin: null
LoginValve: 2019-02-02T15:58:10.006 sid: F75895CAE2521849902CF9894E39A039 UserID: null method: POST requestURI: /app/user/j_security_check reqlogin: null sesslogin: null
LoginValve: 2019-02-02T15:58:10.020 sid: F75895CAE2521849902CF9894E39A039 UserID: null method: GET requestURI: /app/user/index.jsp reqlogin: null sesslogin: null
LoginValve: 2019-02-02T15:58:13.743 sid: 0BBD2544A3C117E32FEE0A03840EAEAE UserID: 3776559 method: GET requestURI: /app/user/transactions.jsp reqlogin: null sesslogin: joe_user
LoginValve: 2019-02-02T15:58:18.127 sid: 0BBD2544A3C117E32FEE0A03840EAEAE UserID: 3776559 method: GET requestURI: /app/user/profile.jsp reqlogin: null sesslogin: joe_user
LoginValve: 2019-02-02T15:58:20.961 sid: 0BBD2544A3C117E32FEE0A03840EAEAE UserID: 3776559 method: GET requestURI: /app/user/feedback.jsp reqlogin: null sesslogin: joe_user
LoginValve: 2019-02-02T15:58:22.930 sid: 0BBD2544A3C117E32FEE0A03840EAEAE UserID: 3776559 method: GET requestURI: /app/user/ reqlogin: null sesslogin: joe_user
LoginValve: 2019-02-02T15:58:24.849 sid: 0BBD2544A3C117E32FEE0A03840EAEAE UserID: 3776559 method: GET requestURI: /app/auth/logoff.jsp reqlogin: null sesslogin: joe_user
LoginValve: 2019-02-02T15:58:24.872 sid: 879B16BB6831D4E07B486C7C0712AE5D UserID: null method: GET requestURI: /app/index.jsp reqlogin: null sesslogin: null

下面是localhost_access_log文件的输出(它使用户登录的 joe_user 从其调用request.getRemoteUser()

127.0.0.1 - joe_user [02/Feb/2019:15:58:06 -0600] "GET /app/auth/logoff.jsp HTTP/1.1" 302 -
127.0.0.1 - - [02/Feb/2019:15:58:06 -0600] "GET /app/index.jsp HTTP/1.1" 200 9303
127.0.0.1 - - [02/Feb/2019:15:58:07 -0600] "GET /app/user/index.jsp HTTP/1.1" 200 6297
127.0.0.1 - - [02/Feb/2019:15:58:10 -0600] "POST /app/user/j_security_check HTTP/1.1" 303 -
127.0.0.1 - joe_user [02/Feb/2019:15:58:10 -0600] "GET /app/user/index.jsp HTTP/1.1" 200 29637
127.0.0.1 - joe_user [02/Feb/2019:15:58:14 -0600] "GET /app/user/transactions.jsp HTTP/1.1" 200 1742146
127.0.0.1 - joe_user [02/Feb/2019:15:58:18 -0600] "GET /app/user/profile.jsp HTTP/1.1" 200 9793
127.0.0.1 - joe_user [02/Feb/2019:15:58:21 -0600] "GET /app/user/feedback.jsp HTTP/1.1" 200 5476
127.0.0.1 - joe_user [02/Feb/2019:15:58:23 -0600] "GET /app/user/ HTTP/1.1" 200 29637
127.0.0.1 - joe_user [02/Feb/2019:15:58:24 -0600] "GET /app/auth/logoff.jsp HTTP/1.1" 302 -
127.0.0.1 - - [02/Feb/2019:15:58:24 -0600] "GET /app/index.jsp HTTP/1.1" 200 9303

同样,问题是,我如何获得对request.getRemoteUser()的调用,以在登录用户通过身份验证后返回他们。

1 个答案:

答案 0 :(得分:1)

  

我的LoginValve是否需要扩展或实现一个类,以便在验证用户身份后返回登录名/用户?

是的,您需要实现Interface AccessLog,该声明在其文档“ 旨在由Valve用来指示Valve提供访问日志记录。”

这是JDBCAccessLogValveAccessLogValve的共同作用。

这是示例代码:

package org.stack;

import java.io.IOException;
import java.time.LocalDateTime;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
import org.apache.catalina.AccessLog;

public class LoginValve extends ValveBase implements AccessLog {

    // Should this valve set request attributes for IP address, hostname, protocol and port used for the request?
    boolean requestAttributesEnabled = false;

    @Override
    public void invoke(Request request, Response response) throws IOException, ServletException {
        // null 
        System.out.println("LoginValve-invoke: " + request.getRemoteUser());
        getNext().invoke(request, response);
    }

    @Override
    public void log(Request request, Response response, long time) {
        // remote user
        System.out.println("LoginValve-log: " + request.getRemoteUser());
    }

    @Override
    public void setRequestAttributesEnabled(boolean requestAttributesEnabled) {
        this.requestAttributesEnabled = requestAttributesEnabled;
    }

    @Override
    public boolean getRequestAttributesEnabled() {
        return requestAttributesEnabled;
    }
}

启用tomcat-users.xml文件以允许在管理器Web应用上进行身份验证时,我得到了肯定的结果:

curl -u stack:stack 'http://localhost:8080/manager/html'
..
$ grep 'LoginValve' catalina.out
LoginValve-invoke: null
LoginValve-log: stack