Artigo Diretório
Um, interface de login
A página de login é a página exibida pelo navegador que você vê, Como isso:
A interface de login é onde os dados de login são enviados, que é o valor correspondente ao atributo de ação do formulário na página de login.
No Spring Security, se não fizermos nenhuma configuração, a página de login padrão e o endereço da interface de login são ambos /login
, ou seja, as duas solicitações a seguir existirão por padrão:
OBTER http: // localhost: 8080 / login
POST http: // localhost: 8080 / login
Se for uma solicitação GET, significa que você deseja acessar a página de login. Se for uma solicitação POST, significa que deseja enviar os dados de login.
No artigo anterior, personalizamos o endereço da página de login em SecurityConfig, da seguinte maneira:
.and()
.formLogin()
.loginPage("/login.html")
.permitAll()
.and()
Quando configuramos o loginPage /login.html
após essa configuração literalmente, é para definir o endereço como a página de login /login.html
.
Na verdade, ele também tem uma operação oculta, o endereço da interface também está definido para entrar no /login.html
. Em outras palavras, a nova página de login e o endereço da interface de login são ambos /login.html
, e agora existem duas solicitações, como segue:
OBTER http: // localhost: 8080 / login.html
POSTAR http: // localhost: 8080 / login.html
A primeira solicitação GET é usada para obter a página de login e a última solicitação POST é usada para enviar os dados de login.
Alguns amigos estão surpresos? Por que a página de login e a interface de login não podem ser configuradas separadamente?
Na verdade, ele pode ser configurado separadamente!
Em SecurityConfig, podemos loginProcessingUrl
especificar o método de endereço da interface de login, da seguinte maneira:
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.permitAll()
.and()
Após essa configuração, o endereço da página de login e o endereço da interface de login são separados, e cada um é separado.
Neste momento, também precisamos modificar o atributo de ação na página de login da /doLogin
seguinte maneira:
<form action="/doLogin" method="post">
<!--省略-->
</form>
Neste ponto, o novo login do projeto de inicialização, descobrimos que o login ainda pode ser bem-sucedido.
Então, por que os dois endereços de configuração são iguais por padrão?
Sabemos que, na forma de configuração FormLoginConfigurer
, a classe herda AbstractAuthenticationFilterConfigurer
, então quando FormLoginConfigurer
o tempo de inicialização, AbstractAuthenticationFilterConfigurer
também será inicializado no AbstractAuthenticationFilterConfigurer
construtor, podemos ver
protected AbstractAuthenticationFilterConfigurer() {
setLoginPage("/login");
}
É assim que o loginPage padrão é configurado /login
.
Por outro lado, FormLoginConfigurer
o método do init
método de inicialização também chama o init
método da classe pai :
public void init(H http) throws Exception {
super.init(http);
initDefaultLoginFilter(http);
}
No método init da classe pai, ele é chamado novamente updateAuthenticationDefaults
. Vamos dar uma olhada neste método:
protected final void updateAuthenticationDefaults() {
if (loginProcessingUrl == null) {
loginProcessingUrl(loginPage);
}
//省略
}
Pela lógica dessa abordagem, podemos ver que, se o usuário não precisar loginProcessingUrl
definir o valor, o padrão usará loginPage
como loginProcessingUrl
.
E se você tiver feito a configuração loginPage
na configuração finalizada loginPage
após o updateAuthenticationDefaults
método ele ainda será chamado neste momento se não houver configuração loginProcessingUrl
, use a nova configuração loginPage
como loginProcessingUrl
.
Bem, vendo isso, acredito que meus amigos entenderão porque a interface de login e o endereço da página de login no início são os mesmos
Dois, parâmetros de login
Depois de falar sobre a interface de login, vamos falar sobre os parâmetros de login.
No artigo anterior, os parâmetros em nosso formulário de login são nome de usuário e senha. Observe que isso não pode ser alterado por padrão:
<form action="/login.html" method="post">
<input type="text" name="username" id="name">
<input type="password" name="password" id="pass">
<button type="submit">
<span>登录</span>
</button>
</form>
Então porque é assim?
Ou voltando à FormLoginConfigurer
aula, em seu construtor, podemos ver que existem duas maneiras de configurar um nome de usuário e senha:
public FormLoginConfigurer() {
super(new UsernamePasswordAuthenticationFilter(), null);
usernameParameter("username");
passwordParameter("password");
}
Aqui, a configuração da primeira classe pai de super chamada, passando a UsernamePasswordAuthenticationFilter
instância que será atribuída aos authFilter
atributos de uma classe pai .
O próximo usernameParameter
método é o seguinte:
public FormLoginConfigurer<H> usernameParameter(String usernameParameter) {
getAuthenticationFilter().setUsernameParameter(usernameParameter);
returnthis;
}
getAuthenticationFilter
Na verdade, o método da classe pai, este método retorna a authFilter
propriedade, que é o início de um conjunto de UsernamePasswordAuthenticationFilter
exemplos, em seguida, chama o setUsernameParameter
método de instância para definir os parâmetros do nome do usuário conectado:
public void setUsernameParameter(String usernameParameter) {
this.usernameParameter = usernameParameter;
}
Qual é a utilidade das configurações aqui? Quando a solicitação de login do navegador para o servidor, precisamos solicitar HttpServletRequest
retirado o nome de usuário de login do usuário e senha de login, como fazer isso? Ou na UsernamePasswordAuthenticationFilter
aula, os dois métodos a seguir:
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
Você pode ver, desta vez, ele usa a configuração padrão username
e password
superior.
Claro, também podemos configurar esses dois parâmetros por nós mesmos, da seguinte maneira:
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.usernameParameter("name")
.passwordParameter("passwd")
.permitAll()
.and()
Depois que a configuração for concluída, modifique também a página front-end:
<form action="/doLogin" method="post">
<div class="input">
<label for="name">用户名</label>
<input type="text" name="name" id="name">
<span class="spin"></span>
</div>
<div class="input">
<label for="pass">密码</label>
<input type="password" name="passwd" id="pass">
<span class="spin"></span>
</div>
<div class="button login">
<button type="submit">
<span>登录</span>
<i class="fa fa-check"></i>
</button>
</div>
</form>
Preste atenção para modificar o valor do atributo name da entrada e a correspondência do servidor.
Após a conclusão da configuração, reinicie o teste de login.
Três, retorno de chamada de login
Depois que o login for bem-sucedido, temos que lidar com a situação de acordo com a situação. De um modo geral, não passam de duas situações:
Login separado de front-end e back-end
Os dois casos são tratados de forma diferente. Neste artigo, vamos primeiro examinar o segundo tipo de login, sem distinção entre front ends e back ends. Falarei sobre os callbacks de login com front ends e back ends separados no próximo artigo.
1. Retorno de login de sucesso
No Spring Security, existem dois métodos relacionados ao URL de redirecionamento de login bem-sucedido:
defaultSuccessUrl
successForwardUrl
Não há diferença entre os dois à primeira vista, mas eles realmente escondem o universo.
Primeiro, estamos no momento da configuração, defaultSuccessUrl
e successForwardUrl
só precisamos definir uma configuração específica que depende de suas necessidades, duas diferenças são as seguintes:
(1)
defaultSuccessUrl
existe um método sobrecarregado, começamos com um parâmetro dodefaultSuccessUrl
método. SedefaultSuccessUrl
especificarmos uma página de login para o salto bem-sucedido/index
, em dois casos, se você for inserido diretamente no endereço de login do navegador, após um login bem-sucedido, pule diretamente para/index
, se você for inserido em um navegador os demais endereços, por exemplohttp://localhost:8080/hello
, porque os resultados não estão logados, e redirecionados para a página de login, depois que o login for bem-sucedido dessa vez, eles não virão/index
, mas vieram para/hello
a página.
(2)defaultSuccessUrl
existe um método sobrecarregado, o segundo parâmetro se o padrão não for definidofalse
, ou seja, nós, o caso acima, se você definir manualmente o segundo parâmetro é verdadeiro, adefaultSuccessUrl
eficácia esuccessForwardUrl
consistência.
(3)successForwardUrl
indique não importa de onde você seja, log tudo pule parasuccessForwardUrl
o endereço especificado. Por exemplo,successForwardUrl
endereço especificado/index
, você insere na barra de endereço do navegadorhttp://localhost:8080/hello
, porque os resultados não estão logados, redireciona para a página de login quando você faz o login com sucesso, o servidor irá saltar para a/index
página; ou você diretamente no seu navegador e digite o login O endereço da página também virá após o login bem-sucedido/index
.
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.usernameParameter("name")
.passwordParameter("passwd")
.defaultSuccessUrl("/index")
.successForwardUrl("/index")
.permitAll()
.and()
Nota: Na operação real, apenas um de defaultSuccessUrl e successForwardUrl precisa ser configurado
2. Retorno de chamada de falha de login
Semelhante ao login bem-sucedido, existem dois métodos para login com falha:
failForwardUrl
failureUrl
Você também pode definir um desses dois métodos durante a configuração.
FailForwardUrl é um redirecionamento do lado do servidor após falha de login, e failureUrl é um redirecionamento após falha de login.
Quatro, saia
A interface padrão para logout é /logout
, também podemos configurá-la.
.and()
.logout()
.logoutUrl("/logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout","POST"))
.logoutSuccessUrl("/index")
.deleteCookies()
.clearAuthentication(true)
.invalidateHttpSession(true)
.permitAll()
.and()
Deixe-me falar sobre a configuração de logout:
(1) O URL é o cancelamento padrão
/logout
é uma solicitação GET, podemoslogoutUrl
modificar o método de URL de logout padrão.
(2) OlogoutRequestMatcher
método pode não apenas modificar o URL de logout, mas também modificar o método de solicitação. No projeto real, este método e logoutUrl podem ser definidos arbitrariamente.
(3)logoutSuccessUrl
Indica a página para a qual saltar após o logout ser bem-sucedido.
(4)deleteCookies
Usado para limpar cookies.
(5)clearAuthentication
einvalidateHttpSession
representam a falha clara das informações de autenticação e do HttpSession, você não pode configurar um padrão, o padrão é limpo.