Posso desligar o HttpSession em web.xml?
-
20-09-2019 - |
Pergunta
Gostaria de eliminar completamente o HttpSession - posso fazer isso em web.xml?Tenho certeza de que existem maneiras específicas de fazer isso (que é o que lota os resultados da pesquisa quando faço uma pesquisa no Google).
P.S.Isso é uma má ideia?Prefiro desabilitar completamente as coisas até realmente precisar delas.
Solução
Eu gostaria de eliminar completamente a HttpSession
Você não pode desativá -lo completamente. Tudo que você precisa fazer é apenas não para obter um identificador por qualquer request.getSession()
ou request.getSession(true)
Em qualquer lugar do código do seu aplicativo web e certificando -se de que seus JSPs não façam isso implicitamente, configurando <%@page session="false"%>
.
Se sua principal preocupação é realmente desativar o cookie que é usado nos bastidores de HttpSession
, então você pode no Java EE 5 / Servlet 2.5 apenas na configuração do WebApp específica do servidor. Por exemplo, tomcat, você pode definir o cookies
atribuir a false
dentro <Context>
elemento.
<Context cookies="false">
Veja também isso Documentação específica do tomcat. Dessa forma, a sessão não será retida nas solicitações subsequentes que não são re-reovistadas-apenas sempre que você o pegar do pedido por algum motivo. Afinal, se você não precisar, apenas Não pegue, então não será criado/retido.
Ou, se você já está no Java EE 6 / Servlet 3.0 ou mais recente, e realmente quer fazer isso via web.xml
, então você pode usar o novo <cookie-config>
elemento em web.xml
como segue zero fora da idade máxima:
<session-config>
<session-timeout>1</session-timeout>
<cookie-config>
<max-age>0</max-age>
</cookie-config>
</session-config>
Se você quiser codificar sua aplicação de web para que getSession()
nunca retorna a HttpSession
(ou um "vazio" HttpSession
), então você precisará criar um filtro ouvindo em um url-pattern
do /*
que substitui o HttpServletRequest
com um HttpServletRequestWrapper
implementação que retorna em todos getSession()
métodos null
, ou um costume fictício HttpSession
implementação que não faz nada, ou mesmo joga UnsupportedOperationException
.
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest) request) {
@Override
public HttpSession getSession() {
return null;
}
@Override
public HttpSession getSession(boolean create) {
return null;
}
}, response);
}
PS Isso é uma má ideia? Prefiro desativar completamente as coisas até que eu realmente precise delas.
Se você não precisar deles, apenas não os use. Isso é tudo. Sério :)
Outras dicas
Se você estiver construindo um aplicativo de alta carga apátrida, poderá desativar o uso de cookies para rastreamento de sessão como este (não intrusivo, provavelmente o contêiner-agnóstico):
<session-config>
<tracking-mode>URL</tracking-mode>
</session-config>
Para fazer cumprir essa decisão arquitetônica, escreva algo assim:
public class PreventSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
throw new IllegalStateException("Session use is forbidden");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
throw new IllegalStateException("Session use is forbidden");
}
}
E adicione -o ao web.xml e corrija os lugares onde falha com essa exceção:
<listener>
<listener-class>com.ideas.bucketlist.web.PreventSessionListener</listener-class>
</listener>
Eu uso o seguinte método para meu aplicativo RESTful para remover qualquer cookies de sessão inadvertido de ser criado e usado.
<session-config>
<session-timeout>1</session-timeout>
<cookie-config>
<max-age>0</max-age>
</cookie-config>
</session-config>
No entanto, isso não desativa completamente o HTTPSessions. Uma sessão ainda pode ser criada pelo aplicativo inadvertidamente, mesmo que desapareça em um minuto e um cliente desonesto também possa ignorar a solicitação de idade máxima para o cookie.
A vantagem dessa abordagem é que você não precisa alterar seu aplicativo, apenas web.xml
. Eu recomendaria que você crie um HttpSessionListener
Isso registrará quando uma sessão for criada ou destruída para que você possa rastrear quando ocorrer.
No Spring Security 3 com o Java Config, você pode usar httpsecurity.sessionmanagement ():
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
XML se parece com isso;
<http create-session="stateless">
<!-- config -->
</http>
A propósito, a diferença entre nunca e sem estado
Nunca: a segurança da primavera nunca criará uma HTTPSession, mas usará o httpsession se já existir
Estado de apátrida: a segurança da primavera nunca criará um httpssession e nunca o usará para obter o SecurityContext
Em vez de desabilitar você pode reescrever o URL usando um filtro de reescrita de URL, por exemplo filtro de reescrita tuckey.Isso fornecerá resultados amigáveis ao Google, mas ainda permitirá o tratamento de sessões baseado em cookies.
No entanto, você provavelmente deve desativá-lo para todas as respostas, pois é pior do que apenas um mecanismo de pesquisa hostil.Ele expõe o ID da sessão que pode ser usado para certas explorações de segurança.
Configuração de exemplo para filtro Tuckey:
<outbound-rule encodefirst="true">
<name>Strip URL Session ID's</name>
<from>^(.*?)(?:\;jsessionid=[^\?#]*)?(\?[^#]*)?(#.*)?$</from>
<to>$1$2$3</to>
</outbound-rule>
Gostaria de eliminar completamente o httpsession - posso fazer isso no web.xml? Tenho certeza de que existem maneiras específicas de contêiner de fazer isso
Eu não acho. Desativando o HttpSession
seria uma violação da especificação do servlet que afirma que HttpServletRequest#getSession
deve devolver uma sessão ou criar uma. Portanto, eu não esperaria que um contêiner Java EE forneça essa opção de configuração (que o tornaria não compatível).
Isso é uma má ideia? Prefiro desativar completamente as coisas até que eu realmente precise delas.
Bem, eu realmente não entendo, apenas não coloque nada na sessão se você não quiser usá -la. Agora, se você realmente deseja impedir o uso da sessão, pode usar um Filter
para substituir a solicitação por uma implementação de HttpServletRequestWrapper
substituindo getSession()
. Mas eu não perderia tempo implementando isso :)
Atualizar: Minha sugestão inicial não foi ideal, o "certo" (tosse) maneira seria substituir a solicitação.
A partir do servlet 3.0, você pode fazê -lo para que as sessões não sejam rastreadas pelo contêiner servlet de forma alguma, adicionando código como este ao contextInitialized
método de a ServletContextListener
:
servletContext.setSessionTrackingModes(Collections.emptySet());
Para uma aplicação RESTful, eu simplesmente o invalidarei sempre que o ciclo de vida da solicitação termina. Pode haver algum servidor da web que sempre cria uma nova sessão quando o novo cliente acessa se você liga request.getSession()
ou não.
Não se pode evitar a criação da sessão. Mas você pode verificar se violar seu próprio requisito no final de um ciclo de solicitação. Portanto, crie um filtro de servlet simples, que você coloca como primeiro e depois da cadeia.
chain.doFilter(request, response);
if(request.getSession(false) != null)
throw new RuntimeException("Somewhere request.getSession() was called");