我该如何在servlet过滤器中从URL中提取用户名和密码?

4
我已经创建了一个BasicAuthFilter,其签名如下:
@Override
public void doFilter(ServletRequest request,
                     ServletResponse response,
                     FilterChain chain) throws IOException, ServletException 

如果有人使用正确的Authorization头调用过滤器,则此方法有效。但是,如果在Chrome或Firefox上访问以下URL:

http://username:password@localhost:8888

浏览器没有将授权信息放入Authorization头中(这让我感到惊讶)。我查看了Chrome发送的信息,发现用户名和密码在请求URL中,但其他地方都没有。我不知道如何从URL中提取这些信息。我已经尝试了许多HttpServletRequest的getter函数,但没有找到能给我用户名和密码的内容。
注意:是的,我知道这很不安全,但在测试系统时使用它确实非常方便。

1
你可以手动解析URL字符串... - Code-Apprentice
1
如果您执行String url = request.getRequestURI();并手动解析它,会发生什么? - Jan Vladimir Mostert
2
@JanVladimirMostert,它包含了我的主机后面的路径。 - Daniel Kaplan
@MonadNewb 我很想这样做,但我不确定如何获取完整的URL。我已经对此进行了一些研究,但每当我尝试时,URL中都没有用户名/密码。 - Daniel Kaplan
我有点困惑。你的问题是关于从URL中提取用户名和密码,但现在你说URL没有用户名和密码。你似乎在这里说了两件相互矛盾的事情。你能否请澄清一下? - Code-Apprentice
1
@MonadNewb 过滤器正在接收来自浏览器的请求。我没有 URL 对象,而是有一个 ServletRequest。我想知道如何从该参数中获取用户名和密码。 - Daniel Kaplan
4个回答

5
    URL url = new URL(custom_url);
    String userInfo = url.getUserInfo();

    String[] userInfoArray = userInfo.split(":");
    System.out.println("username"+userInfoArray[0]);
    System.out.println("password"+userInfoArray[1]);   

4

我的同事发现这个帖子表明在现代浏览器中这是不可能的。出于安全原因,它们拒绝发送url中的用户名:密码部分。


请从Authorization头中提取所需内容,就像我建议的那样。你没有收到该头部信息很奇怪 - 我首先会尝试使用端口8080,如果不行,再尝试在远程机器上(而非本地主机)进行测试,以便隔离问题。 - Nir Alfasi

-2

关于含有'@'的密码,例如"http://user:p@ssw0rd@private.uri.org/some/service"

    final String authority = uri.getAuthority();

    if (authority != null) {
        final String[] userInfo = authority.split(":", 2);

        if (userInfo.length > 1) {
            this.username = userInfo[0];
            int passDelim = userInfo[1].lastIndexOf('@');

            if (passDelim != -1) {
                this.password = userInfo[1].substring(0, passDelim);
            }
        }
    }

请注意,在这种情况下尝试使用 getUserInfo() 是无效的,因为 URIuserInfonull

-2

我会在这个答案上添加一些内容。

如果密码包含字符:,则必须在拆分时指定限制。

所以:

String[] userInfoArray = userInfo.split(":");

变成:

String[] userInfoArray = userInfo.split(":", 2);

2 表示模式 : 只应用一次(因此结果长度数组最多为 2)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接