Boas Práticas para Utilização de Sessões HTTP
Este tópico apresenta as boas práticas para a implementação de sessões HTTP.
- Ative a integração de segurança para proteger sessões HTTP
As sessões HTTP são identificadas por IDs de sessão. Um ID de sessão é um número pseudo-aleatório gerado no tempo de execução. O sequestro de sessão é um ataque conhecido a sessões HTTP e pode ser impedido se todos os pedidos que circularem pela rede forem obrigados a usar por uma conexão segura (ou seja, HTTPS). Mas nem toda configuração em um ambiente de cliente impõe esta restrição devido ao impacto sobre o desempenho de conexões SSL. Devido a este modo abrandado, a sessão HTTP está vulnerável à interceptação e, por causa dessa vulnerabilidade, o WebSphere Application Server tem a opção de integrar rigorosamente as sessões HTTP e a segurança do WebSphere Application Server. Ative a segurança no WebSphere Application Server para que as sessões sejam protegidas de maneira que apenas os usuários que criaram as sessões possam acessá-las.
- Libere objetos HttpSession usando javax.servlet.http.HttpSession.invalidate() quando
concluído.Objetos HttpSession vivem dentro do contêiner da Web até:
- O aplicativo o liberar de forma explícita e programática utilizando o método javax.servlet.http.HttpSession.invalidate; sempre a não validação programática faz parte de uma função de logout do aplicativo.
- O WebSphere Application Server eliminar a HttpSession alocada quando ela expira (padrão = 1800 segundos ou 30 minutos). O WebSphere Application Server pode manter apenas um determinado número de sessões HTTP na memória com base nas configurações de gerenciamento de sessão. No caso de sessões distribuídas, quando o limite máximo de cache for alcançado na memória, o recurso de gerenciamento de sessão remove a que foi utilizada menos recentemente (LRU) do cache para dar espaço a uma sessão.
- Evite tentar salvar e reutilizar o objeto HttpSession fora
de cada servlet ou arquivo JSP.
O objeto HttpSession é uma função do HttpRequest (que pode ser obtido só por meio do método req.getSession) e uma cópia dele é válida somente pela duração do método de serviço do servlet ou arquivo JSP. Não é possível armazenar em cache o objeto HttpSession e referir-se a ele fora do escopo de um servlet ou arquivo JSP.
- Implemente a interface java.io.Serializable ao desenvolver novos
objetos para serem armazenados na sessão HTTP.
A capacidade de ser seriável que uma classe possui é ativada pela classe que implementa a interface java.io.Serializable. A implementação da interface java.io.Serializable permite que o objeto será seriável e modo correto ao usar sessões distribuídas. As classes que não implementam esta interface não terão seus estados seriados ou não seriados. Portanto, se uma classe não implementar a interface Seriável, o JVM não pode persistir seu estado num banco de dados ou em outro JVM. Todos os subtipos de uma classe seriável são seriáveis. Um exemplo disso é o seguinte:
public class MyObject implements java.io.Serializable {...}
Certifique-se de que todos os objeto de variável de instância que não estejam marcados como transientes sejam seriáveis. Não é possível armazenar em cache um objeto não seriável.
Em conformidade com a especificação Java™ Servlet, o contêiner de servlet distribuído deve criar uma exceção IllegalArgumentException para objetos quando não puder suportar o mecanismo necessário para migração da sessão que os armazena. Uma exceção é criada apenas quando você seleciona algo disponível para distribuição.
- Use <codeph>write frequency=END_OF_SERVICE</codeph> ao ativar o failover de estado de sessão para evitar a perda de dados durante o failover com o banco de dados ou o WebSphere eXtreme Scale. A perda de dados é evitada porque os dados de sessão são armazenados no banco de dados ou na grade de dados no final de cada solicitação. Esse comportamento resulta em tempos de solicitação mais longos, que degrada o desempenho.
- Assegure que os objetos Java incluídos em uma sessão estejam no caminho da classe
correto.
Se incluir objetos Java em uma sessão, coloque os arquivos de classe para os objetos no caminho de classe correto (o caminho de classe do aplicativo se estiver usando compartilhamento entre módulos da web em um aplicativo corporativo ou o caminho de classe do módulo da web, se estiver usando o compartilhamento de sessão compatível com Servlet 2.2) ou no diretório que contém outros servlets usados no WebSphere Application Server. No caso de clusters de sessão, essa ação se aplica a cada nó no cluster.
Como o objeto HttpSession é compartilhado entre os servlets que o usuário pode acessar, considere a adoção de convenção de nomenclatura em todo o site, para evitar conflitos.
- Evite armazenar gráficos de objeto grande no objeto HttpSession.
Na maioria dos aplicativos, cada servlet apenas exige uma fração do total de dados da sessão. Entretanto, armazenando os dados no objeto HttpSession como um objeto grande, um aplicativo obriga o WebSphere Application Server a processar todos eles de cada vez.
- Use Afinidade de Sessão para ajudar a alcançar acertos do cache mais latos no WebSphere Application Server.
O WebSphere Application Server tem a funcionalidade no plug-in do Servidor HTTP para ajudar com a afinidade de sessão. O plug-in lê os dados do cookie (ou URL codificado) do navegador e ajuda a direcionar o pedido para o aplicativo ou clone apropriado com base na chave de sessão atribuída. Essa funcionalidade aumenta o uso do cache em memória e reduz ocorrências no banco de dados ou em outra instância do WebSphere Application Server
- Maximize o uso da afinidade de sessão e evite quebrar a afinidade.
O uso correto da afinidade de sessão pode aprimorar o desempenho do WebSphere Application Server. A afinidade de sessão no ambiente do WebSphere Application Server é uma maneira de maximizar o cache em memória dos objetos de sessão e reduzir a quantidade de leituras no banco de dados ou em outra instância do WebSphere Application Server. A autorização de sessão funciona, armazenando em cache os objetos de sessão na instância de servidor do aplicativo com o qual um usuário está interagindo. Se o aplicativo for implementado em vários servidores de um grupo de servidores, o aplicativo poderá direcionar o usuário para qualquer um dos servidores. Se o usuário iniciar no servidor1 e, em seguida, aparecer no servidor2 pouco depois, o servidor precisará gravar todas as informações da sessão na localização externa para que a instância do servidor na qual o servidor2 está executando possa ler o banco de dados. Pode-se evitar essa leitura do banco de dados utilizando autorização de sessão. Com a autorização de sessão, o usuário inicia em servidor1 para o primeiro pedido; em seguida, para cada pedido sucessivo, o usuário é direcionado de volta ao servidor1. O servidor1 precisa olhar apenas para o cache para obter as informações da sessão; o servidor1 nunca tem que fazer uma chamada ao banco de dados da sessão para obter as informações.
Você pode melhorar o desempenho não interrompendo a afinidade de sessão. Algumas sugestões para ajudá-lo a não interromper a afinidade de sessão são:- Combine todos os aplicativos da Web em uma única instância do servidor de aplicativos, se possível, e use modelagem ou clonagem para fornecer suporte de failover.
- Crie a sessão para a página do quadro, mas não crie sessões para as páginas dentro do quadro quando utilizar arquivos JSP multiquadros. (Consulte discussão posterior neste tópico.)
- Ao usar páginas com diversos quadros, siga estas diretrizes:
- Crie uma sessão em apenas um quadro ou antes de acessar qualquer conjunto de quadro. Por exemplo, supondo que ainda não há uma sessão associada ao navegador e que o usuário acessa um arquivo JSP multi-quadros, o navegador emite pedidos simultâneos para os arquivos JSP. Como os pedidos não são parte de nenhuma sessão, os arquivos JSP acabam criando várias sessões e todos os cookies são enviados de volta ao navegador. O navegador atende apenas ao último cookie que chega. Portanto, somente o cliente pode recuperar a sessão associada ao último cookie. Recomenda-se criar uma sessão antes de acessar páginas multi-quadros que utilizem arquivos JSP.
- Por padrão, os arquivos JSP obtêm uma HTTPSession utilizando o método request.getSession(true). Portanto, por padrão os arquivos JSP criam uma nova sessão se nenhuma existir para o cliente. Cada página JSP no navegador está pedindo uma nova sessão, mas somente uma sessão é utilizada por instância do navegador. Um desenvolvedor pode usar <% @ page session="false" %> para desativar a criação de sessão automática a partir de arquivos JSP que não acessam a sessão. Em seguida, se a página precisar de acesso às informações da sessão, o desenvolvedor poderá usar <%HttpSession session = javax.servlet.http.HttpServletRequest.getSession(false); %> para obter a sessão já existente que foi criada pela sessão original criando o arquivo JSP. Essa ação ajuda a evitar a interrupção da afinidade de sessão no carregamento inicial das páginas do quadro.
- Atualize dados da sessão utilizando apenas um quadro. Quando se utilizam conjuntos de quadros, os pedidos vêm para o servidor HTTP simultaneamente. Recomenda-se modificar os dados da sessão dentro de apenas um quadro para que as alterações à sessão não sejam sobrescritas por alterações de sessão no conjunto de quadros simultâneo.
- Evite usar arquivos JSP com diversos quadros nos quais os quadros apontam para diferentes aplicativos da Web. Essa ação resulta na perda da sessão criada por outro aplicativo da Web, pois o cookie JSESSIONID do primeiro aplicativo da Web é sobrescrito pelo JSESSIONID criado pelo segundo aplicativo da Web.
- Proteja todas as páginas (não apenas algumas) ao aplicar a segurança
nos servlets ou arquivos JSP que usam sessões com a integração de segurança
ativada.
Quando se trata de segurança e de sessões, é tudo ou nada. Não faz sentido proteger o acesso ao estado da sessão somente por algum tempo. Quando a integração de segurança for ativada no recurso de gerenciamento de sessão, todos os recursos a partir dos quais uma sessão é criada ou acessada devem ser protegidos ou não protegidos. Não misture recursos com segurança e sem segurança.
O problema em proteger somente algumas páginas é que as sessões criadas em páginas protegidas são criadas com a identidade do usuário autenticado. Somente o mesmo usuário pode acessar sessões em outras páginas protegidas. Para proteger essas sessões do uso por usuários não autorizados, não é possível acessar essas sessões a partir de uma página não protegida. Quando ocorre um pedido a partir de uma página não protegida, o acesso é negado e um erro UnauthorizedSessionRequestException é criado. (UnauthorizedSessionRequestException é uma exceção de tempo de execução; ela é registrada em log para você.)
- Use a atualização manual e o método sync() ou a gravação baseada em tempo
em aplicativos que leem dados da sessão e atualize infrequentemente.
Com END_OF_SERVICE como freqüência de gravação, quando um aplicativo utiliza sessões e a qualquer tempo que dados são lidos dessa sessão ou gravados nela, o campo de hora LastAccess é atualizado. Se forem utilizadas sessões de banco de dados, uma nova gravação ao banco de dados é produzida. Essa atividade é um impacto no desempenho que pode ser evitado utilizando a opção de Atualização Manual e fazendo com que os registros sejam gravados de volta no banco de dados apenas quando os valores dos dados forem atualizados, não em toda leitura ou gravação do registro.
Para utilizar a atualização manual, ative-a no serviço de gerenciamento de sessão. (Consulte as tabelas anteriores para obter informações de local.) Adicionalmente, o código do aplicativo deve usar a classe com.ibm.websphere.servlet.session.IBMSession em vez da HttpSession genérica. No objeto IBMSession há um método sync. Esse método solicita que o WebSphere Application Server grave os dados do objeto de sessão no banco de dados. Essa atividade ajuda o desenvolvedor a melhorar o desempenho geral fazendo com que as informações de sessão persistam apenas quando necessário.
Nota: Uma alternativa à utilização de atualizações manuais é usar as atualizações cronometradas para persistir dados em intervalos de tempo diferentes. Esta ação fornece resultados semelhantes ao esquema de atualização manual. - Implemente as seguintes sugestões para alcançar um alto desempenho:
- Se seus aplicativos não alteram os dados da sessão freqüentemente, utilize a Atualização Manual e a função sync (ou atualização a intervalos cronometrados) para persistir de forma eficiente as informações de sessão.
- Mantenha a menor quantidade possível de dados armazenados na sessão. Com a facilidade de utilizar sessões para conter dados, às vezes, muitos dados ficam armazenados nos objetos da sessão. Determine um equilíbrio apropriado entre armazenamento de dados e desempenho para utilizar sessões eficazmente.
- Se estiver usando sessões de banco de dados, utilize um banco de dados dedicado para o banco de dados da sessão. Evite utilizar o banco de dados do aplicativo. Isto ajuda a evitar contenção para conexões JDBC e permite um melhor desempenho do banco de dados.
- Se estiver utilizando sessões de memória a memória, empregue particionamento (grupo ou réplica simples) à medida que seus clusters crescerem em tamanho e o escalamento diminuir.
- Verifique se você tem os últimos fix packs do WebSphere Application Server.
- Use as ferramentas a seguir para ajudar a monitorar o desempenho da sessão.
- Execute o servlet com.ibm.servlet.customization.sessiontracking.IBMTrackerDebug. - Para executar esse servlet, você deve ter o invocador de servlet em execução no aplicativo da Web a partir do qual deseja executá-lo. Ou você pode configurar explicitamente esse servlet no aplicativo que deseja executar.
- Utilize o Analisador de Recursos do WebSphere Application Server que acompanha o WebSphere Application Server para monitorar sessões ativas e estatísticas do ambiente do WebSphere Application Server.
- Utilize ferramentas de rastreio de banco de dados, como "Monitoramento" no DB2. (Consulte a documentação respectiva para o sistema de banco de dados utilizado.)