【发布时间】:2010-10-03 14:42:52
【问题描述】:
我们在实用程序类中有一个静态方法,该方法将从 URL 下载文件。已设置身份验证器,因此如果需要用户名和密码,则可以检索凭据。问题在于,只要凭据有效,第一个成功连接的凭据就会用于每个连接之后。这是一个问题,因为我们的代码是多用户的,并且由于不会检查每个连接的凭据,因此没有正确凭据的用户可能会下载文件。
这是我们正在使用的代码
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。结果是第一次连接成功后,可以输入无效的凭据,仍然可以成功连接。这可能是因为下载方法是静态的,并且在静态类中吗?
编辑 我忘了提到这是在 tomcat 下运行的 JSF webapp 中 - 也许其中一项技术是在某处设置一些默认凭据?
我已将 URLAuthenticator 提取到它自己的类中,并使其尽可能非静态,但问题仍然存在。我已经读过,如果使用 Authenticator.setDefault(null) 将默认身份验证器设置为 null,那么在 Windows 上将使用 NTLM 身份验证。这不应该是这里的问题,因为我每次都在设置 Authenticator,但我想我会把它扔在那里。 NTLM 身份验证肯定会被使用,因为如果服务器以有权访问下载文件的用户身份运行,则甚至不需要凭据,文件只是下载。所以很明显,有些东西是在调用身份验证器之前获取我的凭据并传递它们。
【问题讨论】:
标签: java