Java 使用自定义身份验证筛选器时使用getRemoteUser()访问用户名

Java 使用自定义身份验证筛选器时使用getRemoteUser()访问用户名,java,servlets,servlet-filters,Java,Servlets,Servlet Filters,简短版本:当我使用自定义身份验证筛选器时,如何获取HttpServletRequest.getRemoteUser()以返回用户名 长版本: 我正在修改一个Tomcat应用程序,该应用程序当前使用声明性安全性(web.xml&Tomcat users.xml),改为使用自定义(由我编写)身份验证过滤器(派生自javax.servlet.filter)。有很多关于如何做到这一点的信息,看起来非常简单 但是,现有应用程序调用了HttpServletRequest.getRemoteUser(),我假

简短版本:当我使用自定义身份验证筛选器时,如何获取
HttpServletRequest.getRemoteUser()
以返回用户名

长版本:

我正在修改一个Tomcat应用程序,该应用程序当前使用声明性安全性(web.xml&Tomcat users.xml),改为使用自定义(由我编写)身份验证过滤器(派生自javax.servlet.filter)。有很多关于如何做到这一点的信息,看起来非常简单

但是,现有应用程序调用了
HttpServletRequest.getRemoteUser()
,我假设除非我在过滤器中设置此属性,否则它将返回null。我找不到有关如何在筛选器中填充
getRemoteUser()
属性的任何信息(没有
setRemoteUser()
)。我发现了一个建议在过滤器中包装请求对象的方法。如果有必要,我会这样做,但我希望有一种侵入性较小的方法来实现这一点


有人能帮忙吗?

是的,修改
HttpServletRequest
HttpServletResponse
的唯一方法是修饰它,并通过覆盖它们为感兴趣的方法提供自己的实现。这是一个带有身份验证过滤器的标准模式,这是
HttpServletRequestWrapper
的目的(响应对应的是
HttpServletResponseWrapper
)。我们这样做是为了包装一个kerberized请求,如下所示

public class KerbHttpServletRequest extends HttpServletRequestWrapper
{
    private Principal myPrincipal;
    private String myAuthType;

    public KerbHttpServletRequest(HttpServletRequest aRequest,
        Principal aPrincipal,
        String aAuthType)
    {
        super(aRequest);
        myPrincipal = aPrincipal;
        myAuthType = aAuthType;
    }

    /**
     * This method returns the Remote User name as user\@domain.com.
     */
    @Override
    public String getRemoteUser()
    {
        return myPrincipal.getName();
    }

    @Override
    public String getAuthType()
    {
        return myAuthType;
    }

    @Override
    public Principal getUserPrincipal()
    {
        return myPrincipal;
    }
}

谢谢,看起来很简单。子问题:我看到您创建了一个
Principal
并覆盖
getUserPrincipal()
。我们在此应用程序中不使用
主体
s。如果我们不重写
getUserPincipal()
而只重写
getRemoteUser()
,我会在某个地方破坏某些东西吗?不,你不会(这是我对kerberos身份验证的特定情况)。您感兴趣的只是getRemoteUser(),只要返回通过运行身份验证协议推导出的值,就足够了(再次假设
HttpServletRequest
的所有客户端都使用getRemoteUser()获得用户登录名)。