Article Directory
One, login interface
The login page is the page displayed by the browser you see, Like this:
The login interface is where the login data is submitted, which is the value corresponding to the action attribute of the form in the login page.
In Spring Security, if we do not do any configuration, the default login page and login interface address are both /login
, that is to say, the following two requests will exist by default:
GET http://localhost:8080/login
POST http://localhost:8080/login
If it is a GET request, it means you want to access the login page. If it is a POST request, it means you want to submit the login data.
In the previous article, we customized the login page address in SecurityConfig, as follows:
.and()
.formLogin()
.loginPage("/login.html")
.permitAll()
.and()
When we configured to loginPage /login.html
after this configuration literally, it is to set the address as the login page /login.html
.
In fact, it also has a hidden operation, the interface address is also set to sign in /login.html
the. In other words, the new login page and login interface address are both /login.html
, and now there are two requests as follows:
GET http://localhost:8080/login.html
POST http://localhost:8080/login.html
The first GET request is used to obtain the login page, and the latter POST request is used to submit the login data.
Some friends are surprised? Why can't the login page and login interface be configured separately?
In fact, it can be configured separately!
In SecurityConfig, we can loginProcessingUrl
specify the login interface address method, as follows:
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.permitAll()
.and()
After this configuration, the login page address and login interface address are separated, and each is separate.
At this time, we also need to modify the action attribute in the login page to be /doLogin
as follows:
<form action="/doLogin" method="post">
<!--省略-->
</form>
At this point, the startup project re-login, we found that the login can still be successful.
So why are the two configuration addresses the same by default?
We know, form in the form of configuration FormLoginConfigurer
, the class inherits from AbstractAuthenticationFilterConfigurer
, so when FormLoginConfigurer
the initialization time, AbstractAuthenticationFilterConfigurer
will also be initialized in the AbstractAuthenticationFilterConfigurer
constructor, we can see
protected AbstractAuthenticationFilterConfigurer() {
setLoginPage("/login");
}
This is how the default loginPage is configured /login
.
On the other hand, FormLoginConfigurer
the initialization method init
method also calls the parent class init
method:
public void init(H http) throws Exception {
super.init(http);
initDefaultLoginFilter(http);
}
In the init method of the parent class, it is called again updateAuthenticationDefaults
. Let's take a look at this method:
protected final void updateAuthenticationDefaults() {
if (loginProcessingUrl == null) {
loginProcessingUrl(loginPage);
}
//省略
}
From the logic of this approach, we can see, if the user does not have to loginProcessingUrl
set the value, the default will use loginPage
as loginProcessingUrl
.
And if you have configured loginPage
in the configuration finished loginPage
after updateAuthenticationDefaults
method it will still be called at this time if there is no configuration loginProcessingUrl
, use the new configuration loginPage
as loginProcessingUrl
.
Well, seeing this, I believe my friends will understand why the login interface and the login page address at the beginning are the same
Two, login parameters
After talking about the login interface, let's talk about the login parameters.
In the previous article, the parameters in our login form are username and password. Note that this cannot be changed by default:
<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>
So why is it so?
Or return to FormLoginConfigurer
class, in its constructor, we can see there are two ways to configure a user name and password:
public FormLoginConfigurer() {
super(new UsernamePasswordAuthenticationFilter(), null);
usernameParameter("username");
passwordParameter("password");
}
Here, the configuration of first super call parent class, passing the UsernamePasswordAuthenticationFilter
instance that will be assigned to a parent class authFilter
attributes.
The next usernameParameter
method is as follows:
public FormLoginConfigurer<H> usernameParameter(String usernameParameter) {
getAuthenticationFilter().setUsernameParameter(usernameParameter);
returnthis;
}
getAuthenticationFilter
Actually the parent class method, this method returns the authFilter
property, which is the beginning of a set of UsernamePasswordAuthenticationFilter
examples, then call the instance setUsernameParameter
method to set the parameters of the logged-in user name:
public void setUsernameParameter(String usernameParameter) {
this.usernameParameter = usernameParameter;
}
What is the use of the settings here? When the login request from the browser to the server, we need to request HttpServletRequest
taken out of the user's login user name and login password, how to take it? Or in the UsernamePasswordAuthenticationFilter
class, the following two methods:
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
You can see, this time, it uses the default configuration username
and password
up.
Of course, we can also configure these two parameters by ourselves, as follows:
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.usernameParameter("name")
.passwordParameter("passwd")
.permitAll()
.and()
After the configuration is complete, also modify the front-end page:
<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>
Pay attention to modify the name attribute value of input and the correspondence of the server.
After the configuration is complete, restart the login test.
Three, login callback
After the login is successful, we have to deal with the situation according to the situation. Generally speaking, it is nothing more than two situations:
Front-end and back-end separate
login
The two cases are handled differently. In this article, let’s first look at the second type of login without distinction between front and back ends. I will talk about the login callbacks with separate front and back ends in the next article.
1. Successful login callback
In Spring Security, there are two methods related to successful login redirect URL:
defaultSuccessUrl
successForwardUrl
There is no difference between the two at first glance, but they actually hide the universe.
First, we at configuration time, defaultSuccessUrl
and successForwardUrl
only need to configure a specific configuration which is depends on your needs, two differences are as follows:
(1)
defaultSuccessUrl
there is an overloaded method, we start with a parameter of thedefaultSuccessUrl
method. If wedefaultSuccessUrl
specify a login page for the successful jump/index
, then two cases, if you are entered directly in the browser sign-in address, after a successful login, jump directly to/index
, if you are entered in a browser the other addresses, for examplehttp://localhost:8080/hello
, because the results are not logged in, and redirected to the login page, after the login is successful this time, they will not come/index
, but came to/hello
the page.
(2)defaultSuccessUrl
there is an overloaded method, the second parameter if the default is not setfalse
, that is, we the above case, if you manually set the second parameter is true, thedefaultSuccessUrl
effectiveness andsuccessForwardUrl
consistency.
(3)successForwardUrl
indicate no matter where you are from, log all jump tosuccessForwardUrl
the specified address. For example,successForwardUrl
specified address/index
, you enter in the browser address barhttp://localhost:8080/hello
, because the results are not logged in, redirect to the login page when you log in successfully, the server will jump to the/index
page; or you directly in your browser and enter login The page address will also come after successful login/index
.
.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.usernameParameter("name")
.passwordParameter("passwd")
.defaultSuccessUrl("/index")
.successForwardUrl("/index")
.permitAll()
.and()
Note: In actual operation, only one of defaultSuccessUrl and successForwardUrl needs to be configured
2. Login failure callback
Similar to successful login, there are two methods for failed login:
failureForwardUrl
failureUrl
You can also set one of these two methods when setting.
failureForwardUrl is a server-side redirect after login failure, and failureUrl is a redirect after login failure.
Four, log out
The default interface for logout is /logout
, we can also configure it.
.and()
.logout()
.logoutUrl("/logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout","POST"))
.logoutSuccessUrl("/index")
.deleteCookies()
.clearAuthentication(true)
.invalidateHttpSession(true)
.permitAll()
.and()
Let me talk about the logout configuration:
(1) The URL is the default cancellation
/logout
is a GET request, we canlogoutUrl
modify the default logout URL method.
(2) ThelogoutRequestMatcher
method can not only modify the logout URL, but also modify the request method. In the actual project, this method and logoutUrl can be arbitrarily set.
(3)logoutSuccessUrl
Indicates the page to jump to after the logout is successful.
(4)deleteCookies
Used to clear cookies.
(5)clearAuthentication
andinvalidateHttpSession
represent the clear failure of the authentication information and the HttpSession, you can not configure a default, the default is cleared.