Directorio de artículos
Uno, interfaz de inicio de sesión
La página de inicio de sesión es la página que muestra el navegador que ve, Me gusta esto:
La interfaz de inicio de sesión es donde se envían los datos de inicio de sesión, que es el valor correspondiente al atributo de acción del formulario en la página de inicio de sesión.
En Spring Security, si no hacemos ninguna configuración, la página de inicio de sesión predeterminada y la dirección de la interfaz de inicio de sesión son ambas /login
, es decir, existirán las siguientes dos solicitudes por defecto:
OBTENGA http: // localhost: 8080 / login
POST http: // localhost: 8080 / login
Si se trata de una solicitud GET, significa que desea acceder a la página de inicio de sesión, si es una solicitud POST, significa que desea enviar los datos de inicio de sesión.
En el artículo anterior, personalizamos la dirección de la página de inicio de sesión en SecurityConfig, de la siguiente manera:
.and()
.formLogin()
.loginPage("/login.html")
.permitAll()
.and()
Cuando configuramos para loginPage /login.html
después de esta configuración literalmente, es para establecer la dirección como la página de inicio de sesión /login.html
.
De hecho, también tiene una operación oculta, la dirección de la interfaz también está configurada para iniciar sesión en /login.html
. En otras palabras, la nueva página de inicio de sesión y la dirección de la interfaz de inicio de sesión son ambas /login.html
, y ahora hay dos solicitudes de la siguiente manera:
OBTENGA http: // localhost: 8080 / login.html
POST http: // localhost: 8080 / login.html
La primera solicitud GET se utiliza para obtener la página de inicio de sesión y la última solicitud POST se utiliza para enviar los datos de inicio de sesión.
¿Algunos amigos se sorprenden? ¿Por qué no se pueden configurar la página de inicio de sesión y la interfaz de inicio de sesión por separado?
De hecho, ¡se puede configurar por separado!
En SecurityConfig, podemos loginProcessingUrl
especificar el método de dirección de la interfaz de inicio de sesión, de la siguiente manera:
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.permitAll()
.and()
Después de esta configuración, la dirección de la página de inicio de sesión y la dirección de la interfaz de inicio de sesión se separan, y cada una está separada.
En este momento, también necesitamos modificar el atributo de acción en la página de inicio de sesión para que sea /doLogin
como sigue:
<form action="/doLogin" method="post">
<!--省略-->
</form>
En este punto, al volver a iniciar sesión en el proyecto de inicio, descubrimos que el inicio de sesión aún puede ser exitoso.
Entonces, ¿por qué las dos direcciones de configuración son las mismas por defecto?
Sabemos, en forma de configuración FormLoginConfigurer
, la clase hereda AbstractAuthenticationFilterConfigurer
, por lo que cuando FormLoginConfigurer
el tiempo de inicialización, AbstractAuthenticationFilterConfigurer
también se inicializará en el AbstractAuthenticationFilterConfigurer
constructor, podemos ver
protected AbstractAuthenticationFilterConfigurer() {
setLoginPage("/login");
}
Así es como se configura la página de inicio de sesión predeterminada /login
.
Por otro lado, FormLoginConfigurer
el método del init
método de inicialización también llama al init
método de la clase principal :
public void init(H http) throws Exception {
super.init(http);
initDefaultLoginFilter(http);
}
En el método init de la clase padre, se vuelve a llamar updateAuthenticationDefaults
. Echemos un vistazo a este método:
protected final void updateAuthenticationDefaults() {
if (loginProcessingUrl == null) {
loginProcessingUrl(loginPage);
}
//省略
}
De la lógica de este enfoque, podemos ver, si el usuario no tiene que loginProcessingUrl
establecer el valor, el predeterminado usará loginPage
como loginProcessingUrl
.
Y si ha configurado loginPage
en la configuración finalizada loginPage
después del updateAuthenticationDefaults
método, todavía se llamará en este momento si no hay configuración loginProcessingUrl
, use la nueva configuración loginPage
como loginProcessingUrl
.
Bueno, al ver esto, creo que mis amigos entenderán por qué la interfaz de inicio de sesión y la dirección de la página de inicio de sesión al principio son las mismas
Dos, parámetros de inicio de sesión
Después de hablar sobre la interfaz de inicio de sesión, hablemos de los parámetros de inicio de sesión.
En el artículo anterior, los parámetros de nuestro formulario de inicio de sesión son el nombre de usuario y la contraseña. Tenga en cuenta que esto no se puede cambiar de forma predeterminada:
<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>
Entonces, ¿por qué es así?
O volviendo a la FormLoginConfigurer
clase, en su constructor, podemos ver que hay dos formas de configurar un nombre de usuario y contraseña:
public FormLoginConfigurer() {
super(new UsernamePasswordAuthenticationFilter(), null);
usernameParameter("username");
passwordParameter("password");
}
Aquí, la configuración de la primera clase padre de super llamada, pasando la UsernamePasswordAuthenticationFilter
instancia que se asignará a los authFilter
atributos de una clase padre .
El siguiente usernameParameter
método es el siguiente:
public FormLoginConfigurer<H> usernameParameter(String usernameParameter) {
getAuthenticationFilter().setUsernameParameter(usernameParameter);
returnthis;
}
getAuthenticationFilter
En realidad, el método de la clase principal, este método devuelve la authFilter
propiedad, que es el comienzo de un conjunto de UsernamePasswordAuthenticationFilter
ejemplos, luego llama al setUsernameParameter
método de instancia para establecer los parámetros del nombre de usuario que inició sesión:
public void setUsernameParameter(String usernameParameter) {
this.usernameParameter = usernameParameter;
}
¿Cuál es el uso de la configuración aquí? Cuando la solicitud de inicio de sesión del navegador al servidor, debemos solicitar que HttpServletRequest
se elimine el nombre de usuario y la contraseña de inicio de sesión del usuario, ¿cómo tomarlo? O en la UsernamePasswordAuthenticationFilter
clase, los siguientes dos métodos:
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
Puede ver, esta vez, que usa la configuración predeterminada username
y password
más.
Por supuesto, también podemos configurar estos dos parámetros por nosotros mismos, de la siguiente manera:
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.usernameParameter("name")
.passwordParameter("passwd")
.permitAll()
.and()
Una vez completada la configuración, modifique también la página de inicio:
<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 atención a modificar el valor del atributo de nombre de la entrada y la correspondencia del servidor.
Una vez completada la configuración, reinicie la prueba de inicio de sesión.
Tres, devolución de llamada de inicio de sesión
Una vez que el inicio de sesión es exitoso, tenemos que lidiar con la situación de acuerdo con la situación.En términos generales, no son más que dos situaciones:
Inicio de
sesión separado de front-end y back-end
Los dos casos se manejan de manera diferente. En este artículo, veamos primero el segundo tipo de inicio de sesión sin distinción entre front y back end. En el próximo artículo hablaré sobre las devoluciones de llamada de inicio de sesión con front end y back end separados.
1. Devolución de llamada de inicio de sesión correcta
En Spring Security, hay dos métodos relacionados con la URL de redireccionamiento de inicio de sesión exitoso:
defaultSuccessUrl
successForwardUrl
No hay diferencia entre los dos a primera vista, pero en realidad ocultan el universo.
Primero, en el momento de la configuración, defaultSuccessUrl
y successForwardUrl
solo necesitamos configurar una configuración específica que depende de sus necesidades, dos diferencias son las siguientes:
(1)
defaultSuccessUrl
hay un método sobrecargado, comenzamos con un parámetro deldefaultSuccessUrl
método. SidefaultSuccessUrl
especificamos una página de inicio de sesión para el salto exitoso/index
, entonces dos casos, si ingresa directamente en la dirección de inicio de sesión del navegador, después de un inicio de sesión exitoso, salte directamente a/index
, si ingresó en un navegador las otras direcciones, por ejemplohttp://localhost:8080/hello
, debido a que los resultados no se registran y se redirigen a la página de inicio de sesión, después de que el inicio de sesión sea exitoso esta vez, no vendrán/index
, sino que llegaron a/hello
la página.
(2)defaultSuccessUrl
hay un método sobrecargado, el segundo parámetro si el valor predeterminado no está configuradofalse
, es decir, tenemos el caso anterior, si se configura manualmente el segundo parámetro es verdadero, ladefaultSuccessUrl
efectividad y lasuccessForwardUrl
coherencia.
(3)successForwardUrl
indique sin importar de dónde sea, registre todos los saltos asuccessForwardUrl
la dirección especificada. Por ejemplo, lasuccessForwardUrl
dirección especificada/index
, ingresa en la barra de direcciones del navegadorhttp://localhost:8080/hello
, debido a que los resultados no se registran, redirige a la página de inicio de sesión cuando inicia sesión correctamente, el servidor saltará a la/index
página; o usted directamente en su navegador e ingresa inicio de sesión La dirección de la página también aparecerá después de iniciar sesión correctamente/index
.
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.usernameParameter("name")
.passwordParameter("passwd")
.defaultSuccessUrl("/index")
.successForwardUrl("/index")
.permitAll()
.and()
Nota: En el funcionamiento real, solo es necesario configurar uno de defaultSuccessUrl y successForwardUrl
2. Devolución de llamada por error de inicio de sesión
De manera similar al inicio de sesión exitoso, existen dos métodos para el inicio de sesión fallido:
failureForwardUrl
failureUrl
También puede configurar uno de estos dos métodos al configurar.
failureForwardUrl es un redireccionamiento del lado del servidor después de un error de inicio de sesión, y failureUrl es un redireccionamiento después de un error de inicio de sesión.
Cuatro, cerrar sesión
La interfaz predeterminada para cerrar sesión es /logout
, también podemos configurarla.
.and()
.logout()
.logoutUrl("/logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout","POST"))
.logoutSuccessUrl("/index")
.deleteCookies()
.clearAuthentication(true)
.invalidateHttpSession(true)
.permitAll()
.and()
Déjame hablar sobre la configuración de cierre de sesión:
(1) La URL es la cancelación predeterminada
/logout
es una solicitud GET, podemoslogoutUrl
modificar el método de URL de cierre de sesión predeterminado.
(2) EllogoutRequestMatcher
método no solo puede modificar la URL de cierre de sesión, sino también el método de solicitud. En el proyecto real, este método y logoutUrl se pueden configurar arbitrariamente.
(3)logoutSuccessUrl
Indica la página a la que saltar después de que el cierre de sesión sea exitoso.
(4)deleteCookies
Se utiliza para borrar cookies.
(5)clearAuthentication
yinvalidateHttpSession
representan la clara falla de la información de autenticación y HttpSession, no puede configurar un valor predeterminado, el valor predeterminado está borrado.