Spring Song Ge taught you how to customize the form login Security

Spring Security series continues.

Previous video posts, Song Ge and we chatted for a simple basic usage of Spring Security, and together we customized a login page, so look even more dazzling number of login!

Today we continue to carry this form configuration, digging at the other side of the common configuration here. Learning this article, we strongly suggest that you look at the pre-knowledge ( Song Ge hands you started with Spring Security, do not ask how to decrypt a password ), to learn better.

1. Log Interface

Many beginners can not tell login interface and the login page, I also very depressed. I'm still here to say a little bit.

Login page is what you see out of the browser to show the page like the one below:

The login interface is the place to submit registration data, the corresponding value is the action attribute of the form inside the login page form.

In Spring Security, if we do not do any configuration, the default login page address and login interfaces are /login, that is, by default, there is a two requests:

  • GET http://localhost:8080/login
  • POST http://localhost:8080/login

If it is a GET request that you want to visit the login page, if it is a POST request, that you want to submit the login data.

In the last article , we SecurityConfig in the custom login page address is defined as follows:

.and()
.formLogin()
.loginPage("/login.html")
.permitAll()
.and()

When we configured to loginPage /login.htmlafter 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.htmlthe. In other words, the new login page and login interface addresses are /login.html, there are now two requests as follows:

  • GET http://localhost:8080/login.html
  • POST http://localhost:8080/login.html

In front of the GET request to obtain the login page, the back of the POST request to submit the login data.

Some junior partner will feel strange? Why the login page and login configuration interface can not be separated from it?

In fact, it can be configured separately!

In SecurityConfig, we can specify the login interface address by loginProcessingUrl method, as follows:

.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.permitAll()
.and()

After this configuration, the login page address and login interface address parted, each is their own.

At this point we also need to modify the action attribute inside the login page, read /doLoginas follows:

<form action="/doLogin" method="post">
<!--省略-->
</form>

In this case, re-start the project log, we can still find a successful login.

So why two configuration address is the same as in the case of default of it?

We know, form the relevant configuration form in FormLoginConfigurer, the class inherits from AbstractAuthenticationFilterConfigurer, so when FormLoginConfigurer initialization, AbstractAuthenticationFilterConfigurer will be initialized in the constructor AbstractAuthenticationFilterConfigurer, we can see:

protected AbstractAuthenticationFilterConfigurer() {
	setLoginPage("/login");
}

This is the default configuration for the loginPage /login.

On the other hand, the initialization method FormLoginConfigurer 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 in the parent class, and call updateAuthenticationDefaults, we 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 settings, the default on the use of loginPage as loginProcessingUrl.

If you have configured loginPage, after you configure the loginPage, updateAuthenticationDefaults method will still be called at this time if there is no loginProcessingUrl configuration, use the new configuration loginPage as loginProcessingUrl.

Well, I see here, I believe that small partners to understand the interface and login as the login page address why the beginning.

2. login parameters

Then login interface, we then for the login parameters.

In the last article , we have a login form parameters are username and password, note that by default, this can not be changed:

<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, which is assigned to authFilter properties of the parent class.

Next usernameParameter follows:

public FormLoginConfigurer<H> usernameParameter(String usernameParameter) {
	getAuthenticationFilter().setUsernameParameter(usernameParameter);
	return this;
}

getAuthenticationFilter actually a parent class method to return the property authFilter In this method, which is UsernamePasswordAuthenticationFilter example of a start setting, then call the instance method setUsernameParameter to set the login name of the user parameters:

public void setUsernameParameter(String usernameParameter) {
	this.usernameParameter = usernameParameter;
}

Set here what use is it? When the login request from the browser to the server, HttpServletRequest request we want taken out of the user's login user name and login password, how to take it? UsernamePasswordAuthenticationFilter or in the 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, we use the username and password of the default configuration.

Of course, these two parameters we can configure their own set parameters as follows:

.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.usernameParameter("name")
.passwordParameter("passwd")
.permitAll()
.and()

Once configured, you must modify the front 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>

Note that modify the corresponding name attribute value of the input and server.

After configuration is complete, restart log test.

3. Log callback

After login is successful, we have to deal with the points situation, generally speaking, nothing more than two situations:

  • Before and after the end of the separation Login
  • Front and rear ends, regardless Login

Handling two cases are not the same. In this paper we first sign in the front and rear ends of the second card, regardless of the front and rear end of the separation login callback I come back and we go into detail in the next article.

3.1 Login success callback

In Spring Security, a successful login redirect URL and related methods are two:

  • defaultSuccessUrl
  • successForwardUrl

Both first glance no different, in fact, built universe.

First, we at configuration time, defaultSuccessUrl and successForwardUrl can only need to configure a specific configuration which, it depends on your needs, two differences are as follows:

  1. defaultSuccessUrl have an overloaded method, let's say defaultSuccessUrl a method parameter. If we specify a login in defaultSuccessUrl successful jump to the page /index, then two cases, if you are entered directly in the browser sign-in address, after a successful login, you jump directly to /index, if you are in Browser enter a different address, for example http://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 /hellothe page.
  2. There is also a consistent defaultSuccessUrl overloaded method, the second parameter if you do not set the default is false, that is, we the above, if you manually set the second parameter is true, the defaultSuccessUrl effects and successForwardUrl.
  3. successForwardUrl indicate whether you come from, after all Login Jump to successForwardUrl specified address. For example successForwardUrl specified address /index, you enter in the browser address bar http://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 /indexpage; or you directly in the browser input login page address, also came after a successful login /index.

Configuration is as follows:

.and()
.formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/doLogin")
.usernameParameter("name")
.passwordParameter("passwd")
.defaultSuccessUrl("/index")
.successForwardUrl("/index")
.permitAll()
.and()

Note: In practice, defaultSuccessUrl and successForwardUrl only needs one can be.

3.2 Login failed callback

Similar to the successful login, login failure also has two methods:

  • failureForwardUrl
  • failureUrl

These two methods set the time you can also set a . failureForwardUrl login failures occur after the server-side jumps, failureUrl then after the login fails, redirection occurs.

4. Log Out

Log out of the interface is the default /logout, we can also be configured.

.and()
.logout()
.logoutUrl("/logout")
.logoutRequestMatcher(new AntPathRequestMatcher("/logout","POST"))
.logoutSuccessUrl("/index")
.deleteCookies()
.clearAuthentication(true)
.invalidateHttpSession(true)
.permitAll()
.and()

Logout configured to log me about:

  1. Logout URL is the default /logout, is a GET request, we can modify the default logout URL by logoutUrl method.
  2. logoutRequestMatcher method can not only modify logout URL, you can also modify the request mode, the actual project, and this method can be a logoutUrl arbitrarily set.
  3. logoutSuccessUrl write-offs represent a successful jump to the page.
  4. deleteCookies to clear the cookie.
  5. clearAuthentication and invalidateHttpSession represent clear authentication information and the HttpSession failure, you can not configure a default, the default is cleared.

Well, today you want to say, this left some of the front and rear end of the separation of interaction, Song Ge again and we go into detail in the next article.

If you feel achievement, remember to tap in the lower right corner Kane

Published 571 original articles · won praise 6801 · Views 4.7 million +

Guess you like

Origin blog.csdn.net/u012702547/article/details/105202015