Depois que um novo usuário envia um formulário 'Nova conta', quero fazer o login manualmente desse usuário para que ele não precise fazer login na página seguinte.
A página de login do formulário normal passando pelo interceptor de segurança Spring funciona bem.
No controlador de formulário de nova conta, estou criando um UsernamePasswordAuthenticationToken e configurando-o no SecurityContext manualmente:
SecurityContextHolder.getContext().setAuthentication(authentication);
Na mesma página, verifico posteriormente se o usuário está conectado com:
SecurityContextHolder.getContext().getAuthentication().getAuthorities();
Isso retorna as autoridades que defini anteriormente na autenticação. Tudo está bem.
Mas quando esse mesmo código é chamado na página seguinte que carrego, o token de autenticação é apenas UserAnonymous.
Não estou claro por que ele não manteve a autenticação que defini na solicitação anterior. Alguma ideia?
- Pode ter a ver com o ID de sessão não estar configurado corretamente?
- Existe algo que possivelmente está substituindo minha autenticação de alguma forma?
- Talvez eu precise de mais uma etapa para salvar a autenticação?
- Ou há algo que preciso fazer para declarar a autenticação em toda a sessão, em vez de uma única solicitação de alguma forma?
Só estou procurando alguns pensamentos que possam me ajudar a ver o que está acontecendo aqui.
fonte
SecurityContextHolder.getContext().setAuthentication(authentication)
. Funciona e é comum, mas existem sérias deficiências de funcionalidade que você encontrará se simplesmente fizer isso. Para obter mais informações, veja minha pergunta e a resposta: stackoverflow.com/questions/47233187/…Respostas:
Eu tive o mesmo problema que você um tempo atrás. Não consigo me lembrar dos detalhes, mas o código a seguir fez as coisas funcionarem para mim. Este código é usado dentro de um fluxo Spring Webflow, portanto, as classes RequestContext e ExternalContext. Mas a parte mais relevante para você é o método doAutoLogin.
fonte
@Configuration public class WebConfig extends WebSecurityConfigurerAdapter { @Bean @Override public AuthenticationManager authenticationProvider() throws Exception { return super.authenticationManagerBean(); } }
Não consegui encontrar nenhuma outra solução completa, então pensei em postar a minha. Isso pode ser um pouco hack, mas resolveu o problema acima:
fonte
authenticationManager
vem?Por fim, descobri a raiz do problema.
Quando eu crio o contexto de segurança manualmente, nenhum objeto de sessão é criado. Somente quando a solicitação termina o processamento, o mecanismo Spring Security percebe que o objeto de sessão é nulo (quando ele tenta armazenar o contexto de segurança para a sessão depois que a solicitação foi processada).
No final da solicitação, o Spring Security cria um novo objeto de sessão e ID de sessão. No entanto, este novo ID de sessão nunca chega ao navegador porque ocorre no final da solicitação, após a resposta ao navegador ter sido feita. Isso faz com que o novo ID de sessão (e, portanto, o contexto de Segurança contendo meu usuário conectado manualmente) seja perdido quando a próxima solicitação contém o ID de sessão anterior.
fonte
Ative o registro de depuração para obter uma imagem melhor do que está acontecendo.
Você pode saber se os cookies de sessão estão sendo configurados usando um depurador do lado do navegador para examinar os cabeçalhos retornados nas respostas HTTP. (Existem outras maneiras também.)
Uma possibilidade é que SpringSecurity esteja configurando cookies de sessão segura, e sua próxima página solicitada tenha uma URL "http" em vez de uma URL "https". (O navegador não enviará um cookie seguro para um URL "http".)
fonte
O novo recurso de filtragem no Servlet 2.4 basicamente alivia a restrição de que os filtros só podem operar no fluxo de solicitação antes e depois do processamento da solicitação real pelo servidor de aplicativos. Em vez disso, os filtros do Servlet 2.4 agora podem interagir com o despachante de solicitação em cada ponto de despacho. Isso significa que quando um recurso da Web encaminha uma solicitação para outro recurso (por exemplo, um servlet encaminhando a solicitação para uma página JSP no mesmo aplicativo), um filtro pode estar operando antes que a solicitação seja tratada pelo recurso de destino. Isso também significa que, se um recurso da Web incluir a saída ou função de outros recursos da Web (por exemplo, uma página JSP incluindo a saída de várias outras páginas JSP), os filtros do Servlet 2.4 podem funcionar antes e depois de cada um dos recursos incluídos. .
Para ativar esse recurso, você precisa:
web.xml
RegistrationController
fonte
Eu estava tentando testar um aplicativo extjs e depois de definir com sucesso um testingAuthenticationToken, isso de repente parou de funcionar sem uma causa óbvia.
Não consegui fazer com que as respostas acima funcionassem, então minha solução foi pular essa parte da primavera no ambiente de teste. Eu introduzi uma costura na primavera como esta:
O usuário é um tipo personalizado aqui.
Em seguida, estou envolvendo-o em uma classe que tem apenas uma opção para o código de teste alternar para fora.
A versão de teste tem a seguinte aparência:
No código de chamada, ainda estou usando um usuário apropriado carregado do banco de dados:
Obviamente, isso não será adequado se você realmente precisar usar a segurança, mas estou executando uma configuração sem segurança para a implantação de teste. Achei que outra pessoa pudesse passar por uma situação semelhante. Este é um padrão que usei para simular dependências estáticas antes. A outra alternativa é que você pode manter a estática da classe de invólucro, mas eu prefiro esta porque as dependências do código são mais explícitas, já que você precisa passar CurrentUserAccessor para as classes onde é necessário.
fonte