重置身份验证器凭据 [英] Reset the Authenticator credentials

查看:114
本文介绍了重置身份验证器凭据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在实用程序类中有一个静态方法,它将从URL下载文件。已设置验证器,因此如果需要用户名和密码,则可以检索凭据。问题是,只要凭证有效,第一次成功连接的凭证就会用于每个连接后的字。这是一个问题,因为我们的代码是多用户的,并且由于没有为每个连接检查凭据,因此没有正确凭据的用户可能会下载文件。

We have a static method in a utility class that will download a file from a URL. An authenticator has been set up so that if a username and password is required, the credentials can be retrieved. The problem is that the credentials from the first successful connection are used for every connection afterwords, as long as the credentials are valid. This is a problem because our code is multi user, and since the credentials are not checked for every connection, it's possible that a user without proper credentials could download a file.

这是我们正在使用的代码

Here's the code we're using

private static URLAuthenticator auth;

public static File download(String url, String username, String password, File newFile)
{
    auth.set(username, password);
    Authenticator.setDefault(auth);
    URL fURL = new URL(url);
    OutputStream out = new BufferedOutputStream(new FileOutputStream(newFile));
    URLConnection conn = fURL.openConnection();
    InputStream in = conn.getInputStream();

    try
    {
        copyStream(in, out);
    }
    finally
    {
        if (in != null)
            in.close();
        if (out != null)
            out.close();
    }

    return newFile;
}

public class URLAuthenticator extends Authenticator
{
    private String username;
    private String password;

    public URLAuthenticator(String username, String password)
    {
         set(username, password);
    }

    public void set(String username, String password)
    {
        this.username = username;
        this.password = password;
    }

    protected PasswordAuthentication getPasswordAuthentication()
    {
        log.debug("Retrieving credentials '" + username + "', '" + password + "'.");
        return new PasswordAuthentication(username, password.toCharArray());
    }
}

我只看到来自getPasswordAuthentication的日志语句一次,第一次下载文件。在第一次成功尝试之后,即使已重置凭据,也不会再次调用getPasswordAuthentication。结果是,在第一次成功连接后,可以输入无效凭证,并且仍然可以成功建立连接。这可能是因为下载方法是静态的,而且是静态类吗?

I only see the log statement from getPasswordAuthentication once, the first time that a file is downloaded. After that first successful attempt, getPasswordAuthentication is not called again, even though the credentials have been reset. The result is that after the first successful connection, invalid credentials can be entered, and a successful connection can still be made. Is this possibly a result of the download method being static, and in a static class?

编辑
我忘记提及这是在tomcat下运行的JSF webapp中 - 也许其中一种技术是在某处设置一些默认凭据?

Edit I forgot to mention that this is in a JSF webapp running under tomcat - maybe one of those technologies is setting some default credentials somewhere?

我已将URLAuthenticator拉出到自己的类中,并且尽可能使它成为非静态的,但问题仍然存在。我已经读过如果使用Authenticator.setDefault(null)将默认验证器设置为null,那么在Windows上将使用NTLM验证。这应该不是问题,因为我每次都设置Authenticator,但我想我会把它扔出去。 NTLM身份验证肯定会被使用,因为如果服务器作为可以访问下载文件的用户运行,则甚至不会要求凭据,该文件只是下载。因此,在调用身份验证器之前,显然是抓住我的凭据并传递它们。

I've pulled the URLAuthenticator out into its own class, and made it as non-static as possible, but the problem still exists. I've read that if the default authenticator is set to null with Authenticator.setDefault(null), then on windows the NTLM authentication will be used. That shouldn't be the problem here since I'm setting the Authenticator everytime, but I thought I'd throw it out there. The NTLM authentication is definately getting used, because if the server is run as a user that has access to the downloaded file, the credentials aren't even asked for, the file just downloads. So something obviously is grabbing my credentials and passing them in before the authenticator is called.

推荐答案

我至少想到了一些东西。看来这种行为是错误。解决方法是使用Sun特定的类来显式重置缓存,如下所示:

I've figured something out at least. It appears that this behavior is a bug. A workaround is to use a Sun specific class to explicitly reset the cache, like so:

import sun.net.www.protocol.http.AuthCacheValue;
import sun.net.www.protocol.http.AuthCacheImpl;
....
AuthCacheValue.setAuthCache(new AuthCacheImpl());
Authenticator.setDefault(new URLAuthenticator(username, password));

我正在重置问题中描述的下载功能顶部的AuthCache。在编译期间,您将收到有关使用这些类的警告。这并不能完全解决问题:如果NTLM身份验证有效,则仍然无法调用身份验证器,但只要服务器在没有所请求文件权限的用户下运行,就应该清除缓存out。

I'm resetting the AuthCache at the top of the download function described in the question. During compile, you'll get warnings about using these classes. This doesn't completely fix the problem: if NTLM authentication works, the authenticator still won't get called, but as long as the server is running under a user that has does not have permission for the requested file, this should clear the cache out.

这篇关于重置身份验证器凭据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆