Estou com um “pequeno” problema e gostaria de saber se o que eu quero é possível.
Eu quero criar um servlet que busque uma página de outro servidor e a envie para o usuário como se a página estivesse no meu servidor. Além disso, quando o usuário fizer uma requisição dentro dessa página (enviar um formulário, por exemplo), esse servlet deverá redirecionar essa requisição (POST e GET) para o servidor que forneceu a página e devolver o resultado (uma outra página qualquer) devolta ao usuário.
Eu preciso fazer isso por dois motivos:
Como não posso incluir um código (server-side) na página do outro servidor, preciso autenticar o usuário e determinar se ele pode ou não acessar aquela página através do meu servidor.
O usuário NÃO PODE SABER A URL DA PÁGINA! Pois essa página não possui autenticação e, caso o usuário descubra a url dela, ele poderia repassar essa url para pessoas que, de outra forma, não deveriam ter acesso à ela.
Vocês sabem se isso é possível? Se for, como ficaria a implementação disso? Se não for possível, existe alguma outra alternativa para o problema?
Eu tinha uma pagina de login em um determinado servidor feito em uma tecnologia, se o usuario fosse aceito seria redirecionado para um outro servidor que estaria utilizando uma outra tecnologia, porém essa pagina deveria estar chumbada, ou seja barra de endereços ocultas e com aparencia de popup;
O unico meio que eu conheço de abrir uma pagina assim é através de javascript:
No meu caso eu trabalhei com os oncomplete dos botoes do prime faces que chamava uma função em js; Esse js fazia uma verificação em um campo hidden com um valor boleano que iria vir direto de um manegedBean. Se fosse true, redirecionava, se fosse false exibia o erro;
No Java não teria uma maneira de executar um POST ou GET pra outro servidor e “escrever” o resultado como html?
Eu tenho quase certeza que seja possível, só não descobri uma maneira de fazer isso, ainda.
Nessa sua solução, o usuário não tinha como descobrir a URL? Botão direito e “Propriedades da Página”? Ou através de algum atalho do navegador que permita reabrir a página numa nova janela? Outro problema são os atalhos do navegador, como, por exemplo, CTRL+P. Quando você imprime uma página, a URL dela fica no rodapé da página. Outro problema é que a URL da página fica armazenada no histórico do navegador.
Com certeza deve ter alguma maneira de “camuflar” a página como sendo do seu servidor, e não de outro. Um exemplo são as páginas chamadas de “Proxy anônimo” que muita gente usa no trabalho para burlar o firewall da empresa e acessar o Orkut, por exemplo. As páginas abertas por esses proxys são carregadas como sendo deles mesmo.
Agora entendi realmente qual a sua dúvida, infelizmente não vou poder te ajudar muito pq isso ja está além do meu conhecimento hahaha
…mas creio que a solução seja algo do tipo;(abstraindo um pouco)Tu cria um servlet que ira analisar as requisições(verificar se usuario esta logado, se tem permissão ou qualquer coisa que seja necessária) e ira se comunicar com um outro servlet, e a resposta deste segundo servlet sera mostrada para o usuario pelo primeiro servlet.
Não sei qual o suporte que java fornece para esse tipo de tarefa, mas creio que seja possível sim!
Criei uma html inicial que possui um formulário com um campo de texto onde o usuário informar a url. Ao enviar esse formulário, o servlet abaixo busca a página usando as classes URL e URLConnection. Então eu uso a biblioteca Jsoup para alterar os atributos HREF e SRC de todos os elementos DOM que estejam como relativo para absoluto (usando como base a url informada pelo usuário). Isso faz com que imagens, scripts e css sejam baixados do servidor certo, e não do meu servidor.
Segue o código-fonte do servlet:
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
public class TunelServlet extends HttpServlet {
private static final long serialVersionUID = -4675061985025674960L;
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Busca a página informada pelo usuário, pegando o html e escrevendo-o
// como sendo do meu servidor.
carregarPagina(request.getParameter("url"), response);
}
private void carregarPagina(String url, HttpServletResponse response) {
response.setContentType("text/html");
try {
URL pagina = new URL(url);
PrintWriter out = response.getWriter();
// Pega o html da página solicitada, fazendo um "parse" para que
// os elementos DOM possam ser extraídos e acessados.
Document doc = Jsoup.parse(pagina, 3*1000);
// Navega por cada elemento DOM da página...
for (Element e : doc.children()) {
// Se o elemento possuir os atributos HREF e/ou SRC usando
// caminhos relativos, esses atributos são alterados para
// usarem o caminho absoluto.
relativoParaAbsoluto(e);
}
// Escreve o html alterado da página solicitada como se
// fosse uma página do meu servidor.
out.println(doc.outerHtml());
} catch (Exception e) {
e.printStackTrace();
}
}
private void relativoParaAbsoluto(Element e) {
// Se o elemento possuir outros elementos filhos...
for (Element c : e.children()) {
// Chama a mesma função para cada um dos elementos filhos.
relativoParaAbsoluto(c);
}
// Se o elementos possuir o atributo HREF, altera o caminho para
// absoluto.
if (e.attr("href") != "")
e.attr("href", e.absUrl("href"));
// Se o elementos possuir o atributo HREF, altera o caminho para
// absoluto.
if (e.attr("src") != "")
e.attr("src", e.absUrl("src"));
}
}
Ainda falta implementar um forma de redirecionar as requisições de formulários da página carregada para o seu servidor de origem e escrever os resultados como sendo do meu servidor (posso usar o mesmo método usado quando o usuário solicita a página pela primeira vez).
Mas estou com um problema que ainda não sei como resolver:
Eu consegui fazer com que as imagens, scripts externos e css’s externos fossem baixados corretamente pelo browser do usuário (usando a biblioteca Jsoap, como explicado acima). Mas quando os elementos html são criados dinamicamente pelo javascript, eu não consegui alterar os caminhos relativos para absolutos. Acho que o Jsoap não consegue fazer isso. Alguém tem alguma sugestão?