Estou construindo um aplicativo da web com Spring Security que ficará no Amazon EC2 e usará os Elastic Load Balancers da Amazon. Infelizmente, o ELB não oferece suporte a sessões persistentes, portanto, preciso garantir que meu aplicativo funcione corretamente sem sessões.
Até agora, configurei o RememberMeServices para atribuir um token por meio de um cookie, e isso funciona bem, mas quero que o cookie expire com a sessão do navegador (por exemplo, quando o navegador fecha).
Tenho que imaginar que não sou o primeiro a querer usar o Spring Security sem sessões ... alguma sugestão?
spring
spring-security
load-balancing
amazon-ec2
Jarrod Carlson
fonte
fonte
Parece ser ainda mais fácil no Spring Securitiy 3.0. Se estiver usando a configuração de namespace, você pode simplesmente fazer o seguinte:
Ou você pode configurar o SecurityContextRepository como nulo, e nada jamais será salvo dessa forma também .
fonte
Trabalhamos no mesmo problema (injetando um SecurityContextRepository personalizado no SecurityContextPersistenceFilter) por 4 a 5 horas hoje. Finalmente, nós descobrimos. Em primeiro lugar, na seção 8.3 do Spring Security ref. doc, há uma definição de bean SecurityContextPersistenceFilter
E depois dessa definição, há esta explicação: "Alternativamente, você pode fornecer uma implementação nula da interface SecurityContextRepository, que impedirá o contexto de segurança de ser armazenado, mesmo se uma sessão já tiver sido criada durante a solicitação."
Precisávamos injetar nosso SecurityContextRepository personalizado no SecurityContextPersistenceFilter. Portanto, simplesmente mudamos a definição do bean acima com nosso impl customizado e o colocamos no contexto de segurança.
Quando executamos o aplicativo, rastreamos os logs e vimos que SecurityContextPersistenceFilter não estava usando nosso impl customizado, estava usando o HttpSessionSecurityContextRepository.
Depois de algumas outras coisas que tentamos, descobrimos que tínhamos que fornecer nosso impl SecurityContextRepository personalizado com o atributo "security-context-repository-ref" do namespace "http". Se você usar o namespace "http" e quiser injetar seu próprio impl SecurityContextRepository, tente o atributo "security-context-repository-ref".
Quando o namespace "http" é usado, uma definição separada de SecurityContextPersistenceFilter é ignorada. Como copiei acima, o documento de referência. não afirma isso.
Por favor, me corrija se eu entendi mal as coisas.
fonte
Dê uma olhada na
SecurityContextPersistenceFilter
aula. Ele define como oSecurityContextHolder
é preenchido. Por padrão, ele usaHttpSessionSecurityContextRepository
para armazenar o contexto de segurança na sessão http.Implementei esse mecanismo com bastante facilidade, com personalização
SecurityContextRepository
.Veja
securityContext.xml
abaixo:fonte
Na verdade
create-session="never"
, não significa ser completamente sem estado. Há um problema para isso no gerenciamento de problemas do Spring Security.fonte
Depois de lutar com as inúmeras soluções postadas nesta resposta, para tentar fazer algo funcionar ao usar a
<http>
configuração do namespace, finalmente encontrei uma abordagem que realmente funciona para meu caso de uso. Na verdade, não exijo que o Spring Security não inicie uma sessão (porque eu uso a sessão em outras partes do aplicativo), apenas que ele não "lembre" de autenticação na sessão (deve ser verificado novamente cada pedido).Para começar, não consegui descobrir como fazer a técnica de "implementação nula" descrita acima. Não estava claro se você deveria definir securityContextRepository como
null
ou como uma implementação autônoma. O primeiro não funciona porque umNullPointerException
é jogado dentroSecurityContextPersistenceFilter.doFilter()
. Quanto à implementação no-op, tentei implementar da maneira mais simples que poderia imaginar:Isso não funciona no meu aplicativo, por causa de alguma coisa estranha
ClassCastException
relacionada aoresponse_
tipo.Mesmo supondo que consegui encontrar uma implementação que funcione (simplesmente não armazenando o contexto na sessão), ainda há o problema de como injetar isso nos filtros construídos pela
<http>
configuração. Você não pode simplesmente substituir o filtro naSECURITY_CONTEXT_FILTER
posição, conforme os documentos . A única maneira que encontrei de me conectar com oSecurityContextPersistenceFilter
que é criado sob as cobertas foi escrever umApplicationContextAware
feijão feio :De qualquer forma, para a solução que realmente funciona, embora muito hackeada. Basta usar um
Filter
que exclua a entrada de sessão queHttpSessionSecurityContextRepository
procura quando faz o que deve:Então, na configuração:
fonte
WebSecurityConfigurerAdapter
com "http.addFilterBefore(new SpringSecuritySessionDeletingFilter(), SecurityContextPersistenceFilter.class)
"Apenas uma nota rápida: é "criar sessão" em vez de "criar sessões"
criar sessão
Controla a ansiedade com que uma sessão HTTP é criada.
Se não for definido, o padrão é "ifRequired". Outras opções são "sempre" e "nunca".
A configuração desse atributo afeta as propriedades allowSessionCreation e forceEagerSessionCreation de HttpSessionContextIntegrationFilter. allowSessionCreation sempre será true, a menos que este atributo seja definido como "never". forceEagerSessionCreation é "false", a menos que seja definido como "always".
Portanto, a configuração padrão permite a criação de sessão, mas não a força. A exceção é se o controle de sessão simultânea estiver habilitado, quando forceEagerSessionCreation será definido como verdadeiro, independentemente da configuração aqui. Usar "nunca" causaria uma exceção durante a inicialização de HttpSessionContextIntegrationFilter.
Para obter detalhes específicos sobre o uso da sessão, há uma boa documentação no javadoc HttpSessionSecurityContextRepository.
fonte
auto-config=false
, aparentemente você não pode substituir o que está naSECURITY_CONTEXT_FILTER
posição pelo seu. Tenho tentado desabilitá-lo com algumApplicationContextAware
bean (usando reflexão para forçar osecurityContextRepository
a uma implementação nulaSessionManagementFilter
), mas sem dados. E, infelizmente, não posso mudar para o spring-security 3.1 ano que forneceriacreate-session=stateless
.