Autenticação JCIFS NTLM para conexões HTTP no GlassFish (ou qualquer servlet container)
Pergunta
Eu criei uma classe Java que se conecta a um site IIS que exigem autenticação NTLM. A classe Java usa a biblioteca JCIFS e é baseado no exemplo a seguir:
Config.registerSmbURLHandler();
Config.setProperty("jcifs.smb.client.domain", domain);
Config.setProperty("jcifs.smb.client.username", user);
Config.setProperty("jcifs.smb.client.password", password);
URL url = new URL(location);
BufferedReader reader = new BufferedReader(
new InputStreamReader(url.openStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
O exemplo funciona bem quando executado a partir do prompt de comando, mas assim que eu tento usar o mesmo código em um contêiner de servlet (especificamente GlassFish), recebo uma IOException
contendo a mensagem "O servidor retornou código de resposta HTTP: 401 para URL:. .... "
Eu tentei movendo o frasco JCIFS ao classpath do sistema (% GLASSFISH% / lib), mas isso não parece fazer qualquer diferença.
As sugestões são muito apreciados.
Solução
Parece que o que eu estava tentando fazer já é suportada em Java 5/6 e eu estava, portanto, capaz de soltar a API JCIFS e fazer algo parecido com isto em vez disso:
public static String getResponse(final ConnectionSettings settings,
String request) throws IOException {
String url = settings.getUrl() + "/" + request;
Authenticator.setDefault(new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
System.out.println(getRequestingScheme() + " authentication")
// Remember to include the NT domain in the username
return new PasswordAuthentication(settings.getDomain() + "\\" +
settings.getUsername(), settings.getPassword().toCharArray());
}
});
URL urlRequest = new URL(url);
HttpURLConnection conn = (HttpURLConnection) urlRequest.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("GET");
StringBuilder response = new StringBuilder();
InputStream stream = conn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(stream));
String str = "";
while ((str = in.readLine()) != null) {
response.append(str);
}
in.close();
return response.toString();
}
Outras dicas
Parece que JCIFS não tem o direito de estabelecer uma fábrica para lidar com suas URLs dentro Glassfish. Você deve verificar as definições de política (checkSetFactory).
A configuração # registerSmbURLHandler () pode engolir o SecurityException.