SpringSecurity login authentication to achieve separation of the front and rear end of the project


I. Introduction The

This paper introduces the basic principle and spring security, and based on springboot integrate spring security to achieve a user-based database administration login and logout, login verification process to achieve a functional verification code.

Two, spring security framework Introduction

  Spring Security is able to provide a secure access control declarative security framework Spring-based solutions for enterprise applications. Including: the user authentication (the Authentication) and user authorization (the Authorization) two portions. User authentication refers to validate a user can access the system. User authentication process generally requires the user to provide a user name and password. System to complete the certification process by verifying user name and password. User authorization refers to verify that a user has to perform an action or access a page permissions. Usually an enterprise-class system in different user has permissions are different, simple terms such as the difference between ordinary users and administrators, administrators apparently have a higher authority. In general, the system will assign different roles for different users, and each character corresponds series of permissions. spring security main core functionality for authentication and authorization, all the architecture is based on two core functions to achieve.

Three, spring security principle

  Spring security provides a set of Bean can be configured in the Spring application context, full use of the Spring IoC, DI, and AOP functionality, providing secure access control functions declarative application system, reducing the control of the preparation for the enterprise system security with substantially duplicate work code. Spring Security support for Web security is dependent on a large number of Servlet filters. These filters intercept incoming request, and prior to the application of certain security processing request processing. Spring Security provides a number of filters that can intercept Servlet request and forwarded to authentication and access management decision-making processes these requests, thereby enhancing security.

四、spring boot整合spring security
4.1 准备工作
4.1.1数据库
4.1.2 pom.xml依赖
4.1.3 application.properties
1 spring.datasource.url=jdbc:mysql://localhost:3306/mydb?characterEncoding=utf8&useSSL=false&serverTimezone=GMT
2 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
3 spring.datasource.username=root
4 spring.datasource.password=

4.2 code implementation
4.2.1 t_user table SysUser basic entity classes of
substantially change search deletions entity class may be required to select the appropriate item based ORM framework itself, where I used the basic user query operation implemented mybatis

4.2.2 generated codes tool

Code production tools CaptchaController.java


/ **
* operation processing codes
*
* @authors
* /
@RestController
public class CaptchaController
{
@Autowired
Private RedisCache redisCache;

/ **
* generated codes
* /
@GetMapping ( "/ captchaImage")
public AjaxResult the getCode (the HttpServletResponse Response) throws IOException
{
// generates a random string
String verifyCode VerifyCodeUtils.generateVerifyCode = (. 4);
// uniquely identifies
String uuid = IdUtils.simpleUUID ();
String verifyKey Constants.CAPTCHA_CODE_KEY + = UUID;

redisCache.setCacheObject(verifyKey, verifyCode, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
// 生成图片
int w = 111, h = 36;
ByteArrayOutputStream stream = new ByteArrayOutputStream();
VerifyCodeUtils.outputImage(w, h, stream, verifyCode);
try
{
AjaxResult ajax = AjaxResult.success();
ajax.put("uuid", uuid);
ajax.put("img", Base64.encode(stream.toByteArray()));
return ajax;
}
catch (Exception e)
{
e.printStackTrace();
return AjaxResult.error(e.getMessage());
}
finally
{
stream.close();
}
}
}

 

 

4.2.3 custom user information categories CustomUserDetails TUser integrated entity classes and implement interfaces UserDetails security provided
UserDetails is true for building secure user (UserDetails) SpringSecurity login, that is, in the process springsecurity user authentication in through UserDetails implementation class to get the user information and authorization verification. do not understand? It does not matter, continue to read
copy the code
. 1 Package com.shf.security.security.config;
2
. 3 Import com.shf.security.user.entity.TUser;
. 4 Import org.springframework.security.core.GrantedAuthority;
. 5 Import ORG .springframework.security.core.userdetails.UserDetails;
. 6
. 7 Import java.util.Collection;
. 8
. 9 / **
10 * description: custom UserDetails, so UserDetails solid structure having the TUser
. 11 *
12 is @author SHF *
13 is * @ 2019/4/19 10:30 DATE
14 @Version V1.0 *
15 ** /
16 public class CustomUserDetails extends TUser implements UserDetails {
17 public CustomUserDetails(TUser tUser){
18 if(null != tUser){
19 this.setId(tUser.getId());
20 this.setCode(tUser.getCode());
21 this.setCreateTime(tUser.getCreateTime());
22 this.setUpdateTime(tUser.getUpdateTime());
23 this.setUsername(tUser.getUsername());
24 this.setPassword(tUser.getPassword());
25 this.setIsDelete(tUser.getIsDelete());
26 this.setEmail(tUser.getEmail());
27 this.setPhone(tUser.getPhone());
28 this.setRole(tUser.getRole());
29 }
30 }
31 @Override
32 public Collection<? extends GrantedAuthority> getAuthorities() {
33 return null;
} 34 is
35
36 @Override
37 [isAccountNonExpired public Boolean () {
38 is return to true;
39}
40
41 is @Override
42 is public Boolean isAccountNonLocked () {
43 is return to true;
44 is}
45
46 is @Override
47 isCredentialsNonExpired public Boolean () {
48 return to true ;
49}
50
51 is @Override
52 is isEnabled public Boolean () {
53 is return to true;
54 is}
55}
copy the code
4.2.4 Create CustomUserDetailsService UserDetailsService class implements interfaces
in CustomAuthenticationProvider class will be referred to hereinafter, is the core of the security verification class , calls CustomUserDetailsService in overridden method loadUserByUsername

Copy the code
. 1 Package com.shf.security.security.config;
2
. 3 Import com.shf.security.user.entity.TUser;
. 4 Import com.shf.security.user.service.TUserService;
. 5 Import the org.springframework.beans .factory.annotation.Autowired;
. 6 Import org.springframework.security.core.userdetails.UserDetails;
. 7 Import org.springframework.security.core.userdetails.UserDetailsService;
. 8 Import org.springframework.security.core.userdetails.UsernameNotFoundException;
. 9 org.springframework.stereotype.Component Import;
10
. 11 / **
12 is * description: the UserDetailsService custom, user information is read from a database, to achieve login authentication
13 is *
14 * @author SHF
15 * @date 2019/4/21. 17: 21 is
16 * @Version V1.0
. 17 ** /
@Component 18 is
. 19 {public class CustomUserDetailsService the implements the UserDetailsService
20 is @Autowired
21 is that userService Private TUserService;
22 is
23 is / **
24 * authentication process - obtaining detailed information from the user registration information
25 *
26 is * @param username login user name entered by the user
27 @return *
28 * @throws UsernameNotFoundException
29 * /
30 @Override
31 is the UserDetails public loadUserByUsername (String username) throws UsernameNotFoundException {
32 // user information input by the user, the query has been registered in the user information database
33 TUser user = userService.findByName ( username);
34 is directly // throws exception if the user does not exist UsernameNotFoundException
35 if (user == null) throw new UsernameNotFoundException ( " user name" + username + "user absent");
36 return new new CustomUserDetails (user) ;
37}
38}
copy the code

4.2.5 New Class CustomWebAuthenticationDetails class inherits WebAuthenticationDetails
similar UserDetails class provides us with the same user details, WebAuthenticationDetails provide us with information about the user's login request (that is, application login username and password information for the user), springsecurity default only verify the user's username and password information, so if we want to achieve verification code needs to be rewritten WebAuthenticationDetails class, it can get HttpServletRequest to verify the code entered by the user.

Copy the code
. 1 Package com.shf.security.security.config;
2
. 3 Import org.springframework.security.web.authentication.WebAuthenticationDetails;
. 4
. 5 Import the javax.servlet.http.HttpServletRequest;
. 6
. 7 / **
. 8 * Description: from defined WebAuthenticationDetails, verification code and the user name, the password AuthenticationProvider brought together
. 9 *
10 * @author SHF
. 11 * @date 2019/4/21 16:58
12 is @Version V1.0 *
13 is ** /
14 public class CustomWebAuthenticationDetails {WebAuthenticationDetails the extends
15 Final static serialVersionUID = Private Long 6975601077710753878L;
16 Final String Private verifyCode;
. 17 CustomWebAuthenticationDetails public (the HttpServletRequest Request) {
18 is Super (Request);
19 verifyCode = request.getParameter("verifyCode");
20 }
21
22 public String getVerifyCode() {
23 return verifyCode;
24 }
25
26 @Override
27 public String toString() {
28 StringBuilder sb = new StringBuilder();
29 sb.append(super.toString()).append("; verifyCode: ").append(this.getVerifyCode());
30 return sb.toString();
31 }
32 }
复制代码

4.2.6 Create CustomAuthenticationDetailsSource AuthenticationDetailsSource class that inherits the class
mentioned above CustomWebAuthenticationDetails codes need to obtain the information by user input HttpServletRequest. AuthenticationDetailsSource class is initialized place CustomWebAuthenticationDetails class, in which we need to pass it to CustomAuthenticationDetailsSource in HttpServletRequest.

Copy the code
. 1 Package com.shf.security.security.config;
2
. 3 Import org.springframework.security.authentication.AuthenticationDetailsSource;
. 4 Import org.springframework.security.web.authentication.WebAuthenticationDetails;
. 5 Import org.springframework.stereotype.Component ;
. 6
. 7 Import the javax.servlet.http.HttpServletRequest;
. 8
. 9 / **
10 * description: custom authenticationDetailsSource, is injected into the HttpServletRequest CustomWebAuthenticationDetails, so that it can obtain the additional information request verification codes
. 11 *
12 is @author * SHF
13 is @date 2019/4/21 17:03 *
14 @Version V1.0 *
15 ** /
16 @Component
17 public class CustomAuthenticationDetailsSource implements AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> {
18 @Override
19 public WebAuthenticationDetails buildDetails(HttpServletRequest request) {
20 return new CustomWebAuthenticationDetails(request);
21 }
22 }
复制代码

4.2.7 implement a custom authenticator (focus), create CustomAuthenticationProvider inherit AbstractUserDetailsAuthenticationProvider class
AbstractUserDetailsAuthenticationProvider class that implements the interface is AuthenticationProvider

复制代码
1 package com.shf.security.security.config;
2
3 import com.shf.security.utils.VerifyCodeUtil;
4 import lombok.extern.slf4j.Slf4j;
5 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.security.authentication.BadCredentialsException;
7 import org.springframework.security.authentication.DisabledException;
8 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
9 import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
10 import org.springframework.security.core.Authentication;
11 import org.springframework.security.core.AuthenticationException;
12 import org.springframework.security.core.userdetails.UserDetails;
13 import org.springframework.stereotype.Component;
14 import org.springframework.web.context.request.RequestContextHolder;
15 import org.springframework.web.context.request.ServletRequestAttributes;
16
17 import javax.servlet.http.HttpServletRequest;
18 import javax.servlet.http.HttpSession;
19
20 /**
21 * 描述:自定义SpringSecurity的认证器
22 *
23 * @Author shf
24 * @Date 2019/4/21 17:30
25 * @Version V1.0
26 **/
27 @Component
28 @Slf4j
29 public class CustomAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {//implements AuthenticationProvider {
30 @Autowired
31 private CustomUserDetailsService userDetailsService;
32
33 @Override
34 protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) throws AuthenticationException {
35
36 }
37
38 @Override
39 public Authentication authenticate(Authentication authentication) throws AuthenticationException {
40 //用户输入的用户名
41 String username = authentication.getName();
42 //用户输入的密码
String password = authentication.getCredentials 43 is () toString ();.
44 is // obtain user input information codes by CustomWebAuthenticationDetails
45 CustomWebAuthenticationDetails Details = (CustomWebAuthenticationDetails) authentication.getDetails ();
46 is verifyCode = details.getVerifyCode String ();
47 IF (== null || verifyCode verifyCode.isEmpty ()) {
48 log.warn ( "not enter the verification code");
49 a NullPointerException the throw new new ( "Please enter PIN");
50}
51 // check codes
IF 52 is (validateVerifyCode (verifyCode)!) {
53 is log.warn ( "input error codes");
54 is the throw new new DisabledException ( "input error codes");
55}
56 // by custom CustomUserDetailsService, user input username queries user information
= CustomUserDetails userDetails and 57 is (CustomUserDetails) userDetailsService.loadUserByUsername (username);
58 // verify the user password
59 IF (userDetails.getPassword () the equals (password)!.) {
60 log.warn ( "wrong password");
61 is the throw new BadCredentialsException ( "wrong password");
62 is}
63 is principalToReturn = userDetails and Object;
64 // stuffed SecurityContext user information, the user information to facilitate access to the current
65 return this.createSuccessAuthentication (principalToReturn, authentication, userDetails and);
66}
67
68 @override
69 protected the UserDetails retrieveUser (String S, the UsernamePasswordAuthenticationToken UsernamePasswordAuthenticationToken) throws of AuthenticationException {
70 return null;
71 is}
72
73 is / **
* 74 input by the user authentication codes
75 * @param inputVerifyCode
76 @return *
77 * /
78 public Boolean validateVerifyCode (String inputVerifyCode) {
79 // Get request object to the current thread bound
80 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder. . getRequestAttributes ()) getRequest ();
81 // this VerifyCodeFactory.SESSION_KEY session is stored in the servlet name
82 request.getSession the HttpSession session = ();
83 String verifyCode = (String) session.getAttribute (VerifyCodeUtil.SESSION_KEY) ;
84 IF (== null || verifyCode verifyCode.isEmpty ()) {
85 log.warn ( "re-authentication request codes expires");
86 DisabledException the throw new new ( "codes expired, please re-authentication");
87}
case-insensitive 88 //
89 verifyCode = verifyCode.toLowerCase ();
90 inputVerifyCode = inputVerifyCode.toLowerCase();
91
92 log.info("验证码:{}, 用户输入:{}", verifyCode, inputVerifyCode);
93
94 return verifyCode.equals(inputVerifyCode);
95 }
96
97 @Override
98 public boolean supports(Class<?> authentication) {
99 return authentication.equals(UsernamePasswordAuthenticationToken.class);
100 }
101 }
复制代码

 

As shown above, the AuthenticationProvider interface provides core security authentication method to authenticate method us, which is the user authentication methods. We custom implementation authenticate method, the general idea is as follows, to obtain user input username, password, verifyCode information CustomWebAuthenticationDetails. Obtain user information (information database of registered users) through CustomUserDetails, and then the user authentication information for comparison. And ultimately the certification process.

Of course, also be implemented directly AuthenticationProvider interface and authenticate method implemented. This is possible but there are ready-made AbstractUserDetailsAuthenticationProvider available, why did they have to write it again? CreateSuccessAuthentication AbstractUserDetailsAuthenticationProvider particular class provides a method, a perfect encapsulated the Authentication (follow-up will continue to mention). AuthenticationProvider of supports direct way to do that is to decide which one AuthenticationProvider implementation class is what we need authenticator.

 

4.2.8 Creating WebSecurityConfig inherit WebSecurityConfigurerAdapter configuration class. (Spring security configuration class)
look at the specific bar code comments, very detailed.

It is worth mentioning that the configuration of the first 81 rows, is the key to achieve ajax login. That is the key code for the front and rear end of the separation project

 

复制代码
1 package com.shf.security.security.config;
2
3 import lombok.extern.slf4j.Slf4j;
4 import org.springframework.beans.factory.annotation.Autowired;
5 import org.springframework.context.annotation.Bean;
6 import org.springframework.context.annotation.Configuration;
7 import org.springframework.security.authentication.AuthenticationDetailsSource;
8 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
9 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
10 import org.springframework.security.config.annotation.web.builders.WebSecurity;
11 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
12 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
13 import org.springframework.security.core.Authentication;
14 import org.springframework.security.core.AuthenticationException;
15 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
16 import org.springframework.security.crypto.password.PasswordEncoder;
17 import org.springframework.security.web.authentication.AuthenticationFailureHandler;
18 import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
19 import org.springframework.security.web.authentication.WebAuthenticationDetails;
20 import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
21
22 import javax.servlet.ServletException;
23 import javax.servlet.http.HttpServletRequest;
24 import javax.servlet.http.HttpServletResponse;
25 import java.io.IOException;
26 import java.io.PrintWriter;
27
28 /**
29 * 描述:
30 *
31 * @Author shf
32 * @Date 2019/4/19 10:54
33 * @Version V1.0
34 **/
35 @Configuration
36 @EnableWebSecurity
37 @Slf4j
38 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
39 @Autowired
40 private CustomAuthenticationProvider customAuthenticationProvider;
41
42 @Autowired
43 private CustomUserDetailsService customUserDetailsService;
44
45 @Autowired
46 private AuthenticationDetailsSource<HttpServletRequest, WebAuthenticationDetails> authenticationDetailsSource;
47
48 @Override
49 protected void configure(AuthenticationManagerBuilder auth) throws Exception {
50 //将自定义的CustomAuthenticationProvider装配到AuthenticationManagerBuilder
51 auth.authenticationProvider(customAuthenticationProvider);
52 //将自定的CustomUserDetailsService装配到AuthenticationManagerBuilder
53 auth.userDetailsService(customUserDetailsService).passwordEncoder(new PasswordEncoder() {
@Override 54 is
55 public String encode (CharSequence CharSequence) {
56 is charSequence.toString return ();
57 is}
58
59 @Override
60 The matches public Boolean (CharSequence CharSequence, String S) {
61 is return s.equals (charSequence.toString ()) ;
62 is}
63 is});
64}
65 @Override
66 public void Configure (HttpSecurity HTTP) throws Exception {
67 HTTP
68 .cors ()
69 .AND () CSRF () disable ();.. // open cross-domain
70 http / * anonymous request: no * log intercepted URL /
71 is .authorizeRequests ()
. 72 .antMatchers ( "/ getVerifyCode") permitAll ()
. 73 is .anyRequest () Authenticated () // other paths are logged before you can access
74 .AND ()
75 / * Login * configuration /
.FormLogin 76 ()
77 .loginPage ( "/ login_page") // login page, when not logged in will be redirected to the page
78 .successHandler (authenticationSuccessHandler ()) // successful login process
79 .failureHandler (authenticationFailureHandler ()) // login failure processing
80 .authenticationDetailsSource (authenticationDetailsSource) // custom validation logic to increase this code
81 .loginProcessingUrl ( "/ login") // restful address registration request
82 .usernameParameter ( "username") // default user name parameter
83 .passwordParameter ( "password") // default password parameter
84 .permitAll ()
85 .AND ()
86 / logout configuration * * /
87 .logout ()
88 .permitAll ()
89 .logoutSuccessHandler (logoutSuccessHandler ( ));
90}
91 is
92 / **
request 93 * security inspection negligible, such as static resources may be required to log on the present configuration at
94 * @param Web
95 * /
96 @Override
97 public void configure(WebSecurity web){
98 // platform.ignoring().antMatchers("/");
99 }
100
101 @Autowired
102 public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
103 auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
104 auth.eraseCredentials(false);
105 }
106 //密码加密配置
107 @Bean
108 public BCryptPasswordEncoder passwordEncoder() {
109 return new BCryptPasswordEncoder(4);
110 }
111 //登入成功
112 @Bean
113 public AuthenticationSuccessHandler authenticationSuccessHandler() {
114 return new AuthenticationSuccessHandler() {
115 /**
116 * 处理登入成功的请求
117 *
118 * @param httpServletRequest
119 * @param httpServletResponse
120 * @param authentication
121 * @throws IOException
122 * @throws ServletException
123 */
124 @Override
125 public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
126 httpServletResponse.setContentType("application/json;charset=utf-8");
127 PrintWriter out = httpServletResponse.getWriter();
128 out.write("{\"status\":\"success\",\"msg\":\"登录成功\"}");
129 out.flush();
130 out.close();
131 }
132 };
133 }
134 //登录失败
135 @Bean
136 public AuthenticationFailureHandler authenticationFailureHandler(){
137 return new AuthenticationFailureHandler() {
138 /**
139 * 处理登录失败的请求
140 * @param httpServletRequest
141 * @param httpServletResponse
142 * @param e
143 * @throws IOException
144 * @throws ServletException
145 */
146 @Override
147 public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
148 httpServletResponse.setContentType("application/json;charset=utf-8");
149 PrintWriter out = httpServletResponse.getWriter();
150 out.write ( "{\" status \ ": \" error \ ", \" msg \ ": \" Login Failed \ "}");
151 out.flush ();
152 the out.close ();
153 }
154};
155}
156 // logout process
157 @Bean
158 public logoutSuccessHandler logoutSuccessHandler () {
159 return new new logoutSuccessHandler () {
160. / **
161 * successful logout request processing
162 *
163 * @param HttpServletRequest
164 is * HttpServletResponse @param
165 * @param authentication
166 @throws IOException *
167 * @throws ServletException
168 * /
169 @Override
170 public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
171 httpServletResponse.setContentType("application/json;charset=utf-8");
172 PrintWriter out = httpServletResponse.getWriter();
173 out.write("{\"status\":\"success\",\"msg\":\"登出成功\"}");
174 out.flush();
175 out.close();
176 }
177 };
178 }
179 }
复制代码

 

4.2.9 LoginController
View Code

4.2.10 UserHolder tools
in their daily business, many business code, we need to get the current user's information. This class is a static utility class.

复制代码
1 package com.shf.security.utils;
2
3 import com.shf.security.user.entity.TUser;
4 import org.springframework.security.core.Authentication;
5 import org.springframework.security.core.context.SecurityContext;
6 import org.springframework.security.core.context.SecurityContextHolder;
7
8 /**
9 * 描述:
10 *
11 * @Author shf
12 * @Description TODO
13 * @Date 2019/4/21 15:24
14 * @Version V1.0
15 **/
16 public class UserHolder {
17 public static TUser getUserDetail(){
18 SecurityContext ctx = SecurityContextHolder.getContext();
19 Authentication auth = ctx.getAuthentication();
20 TUser user = (TUser) auth.getPrincipal();
21 return user;
22 }
23 public static String getUserCode(){
24 SecurityContext ctx = SecurityContextHolder.getContext();
25 Authentication auth = ctx.getAuthentication();
26 TUser user = (TUser) auth.getPrincipal();
27 return user.getCode();
28 }
29 public static int getUserId(){
30 SecurityContext ctx = SecurityContextHolder.getContext();
31 Authentication auth = ctx.getAuthentication();
32 TUser user = (TUser) auth.getPrincipal();
33 return user.getId();
34 }
35 }
复制代码
4.2.10 其他工具类Response.java

View Code

V. Summary of issues

5.1 code issues

In fact, it through the analysis of the second part of the security principle, we can see, spring security is built on a series of filters filter, spring security to filter these requests through the filter layer by layer, and then various login authentication authorization process. Says here it is estimated we will be able to think of another way to achieve CAPTCHA logins. That is, information verification code before the user name and password authentication for user input. UsernamePasswordAuthenticationFilter filter filters the name suggests is a user name and password. So we just need to WebSecurityConfig in addFilterBefore in chapter 4.2.8 () filter configured to perform VerifyCodeFilter before UsernamePasswordAuthenticationFilter filter. It is then performed to verify the validation logic code in VerifyCodeFilter filter.

1 .and()
2 .addFilterBefore(new VerifyCodeFilter(),UsernamePasswordAuthenticationFilter.class)

However, this approach does have a natural disadvantage, which is impossible to do will be unified authentication username and password information in addition to the authenticator in. And if we accidentally verification code in addition to more information needed to verify words. A plurality of n would not write filter.

5.2 seemingly forgot to test Login

Browser requests: http: // localhost: 8080 / user / test

result:

 

It is the result we want.

Login authentication or the use of postman, because spring security default login request only way of handling post. The default browser submits a request is get a restful. and so. . .

Request codes postman

 

postman Login

 

Guess you like

Origin www.cnblogs.com/angelasp/p/11881636.html