Four methods of Spring Boot project authentication

Transferred from: Pillow Book

Link: https://zhenbianshu.github.io/

This paper introduces four ways to implement general auth in spring boot, including traditional AOP, interceptor, parameter parser and filter, and provides the corresponding example code. Finally, it briefly summarizes their execution order.

preface

Recently, I have been inundated by endless business needs and have no time to breathe. Finally, I received a job that allows me to break through the code comfort zone. The process of solving it is very tortuous. For a time, I doubt my life, but the harvest is also great. The code is not obvious, but I feel that I have erased the veil that java, Tomcat and Spring have been blocking in front of me. Their understanding has reached a new level. I haven't output it for a long time, so I chose one aspect to summarize. I hope I can understand some other things in the process of combing.

Due to the prosperous ecology of Java, a large number of articles are devoted to each module below. So I chose another perspective, starting from practical problems, to connect these scattered knowledge. You can take it as a summary. For the ultimate detailed introduction of each module, you can turn to the official documents or see other blogs on the network. The requirements are very simple and clear, which is not the same as the flirtatious requirements proposed by the products: a general appkey whitelist verification function is added to our web framework. I hope it has better scalability.

This web framework is implemented by the Department pioneer based on Spring boot. It is between the business and the Spring framework. It does some business oriented general functions, such as log output, function switch, general parameter parsing, etc. It is usually transparent to the business. Recently, it has been busy doing a good job in requirements and writing code, and has never even noticed its existence.

Traditional AOP

For this requirement, the first thought is of course the AOP interface provided by spring boot. You only need to add the pointcut in front of the Controller method, and then process the pointcut.

realization

Its use steps are as follows:

  1. Use @ Aspect , to declare the facet class , WhitelistAspect;
  2. Add a pointcut '; whitelistPointcut()' in the facet class. In order to realize the ability of flexible assembly of this pointcut, you do not use '; execution' to intercept all, but add an annotation @ Whitelist, and the annotated method will verify the Whitelist.
  3. In the aspect class, use spring's AOP annotation @ Before to declare a notification method, @ checkWhitelist() to check the whitelist Before the Controller method is executed.

The pseudo code of section class is as follows:

@Aspect
public class WhitelistAspect {
   
 @Before(value = "whitelistPointcut() && @annotation(whitelist)")
 public void checkAppkeyWhitelist(JoinPoint joinPoint, Whitelist whitelist) {
     checkWhitelist();
     //You can use} joinpoint Getargs() gets the parameters of the Controller method
     //You can use the whitelist variable to get annotation parameters
 }
   
   
 @Pointcut("@annotation(com.zhenbianshu.Whitelist)")
 public void whitelistPointCut() {
 }
}

Add on Controller method @ Whitelist @ annotation implements the function.

extend

In this example, the annotation is used to declare the pointcut, and I have implemented the annotation parameter to declare the whitelist to be verified. If other whitelists need to be added later, such as verification through UID, methods such as {uid() can be added to this annotation to realize user-defined verification. In addition, spring's AOP also supports pointcut declaration methods such as @ execution (execution method), Bean (execution method of Bean object matching a specific name), and @ Around (executed in the execution of objective function), @ After (After the method is implemented) and other notification methods. In this way, the function has been realized, but the leader is not satisfied = \ =, because AOP is used too much in the project, so I suggest I change it. Well, I have to start it.

Interceptor

Spring's interceptor is also very appropriate to implement this function. As the name suggests, the interceptor is used to judge whether to execute this method through some parameters before the Action in the Controller is executed. To implement an interceptor, you can implement the spring HandlerInterceptor interface.

realization

The implementation steps are as follows:

  1. Define the interceptor class AppkeyInterceptor class and implement the HandlerInterceptor interface.
  2. Implement its pre handle() method;
  3. Judge whether the request needs to be intercepted through annotations and parameters in the preHandle method. When intercepting the request, the interface returns "false";
  4. Register this interceptor in the custom WebMvcConfigurerAdapter class;

The AppkeyInterceptor class is as follows:

@Component
public class WhitelistInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Whitelist whitelist = ((HandlerMethod) handler).getMethodAnnotation(Whitelist.class);
        // whitelist.values(); Get the request parameters through , request , and get the annotation parameters through , whitelist , variable
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  //Method is executed after the Controller method is executed
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  //Execute after the view rendering is complete
    }
}

extend

To enable the interceptor, you need to explicitly configure it. Here, we use WebMvcConfigurerAdapter to configure it. Note that the MvcConfiguration that inherits it needs to be in the ComponentScan path.

@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new WhitelistInterceptor()).addPathPatterns("/*").order(1);
        //Here, you can configure the order of {path} enabled by the interceptor. When multiple interceptors exist, if any interceptor returns {false}, the subsequent request methods will no longer be executed
    }
}

It should also be noted that after the interceptor is successfully executed, the response code is 200, but the response data is empty. The basic Spring Boot tutorial and sample source code can be learned here: https://github.com/javastacks... , very complete. After using the interceptor to realize the function, the leader finally made a big move: we already have an Auth parameter. The appkey can be obtained from the Auth parameter. We can take being out of the white list as a way of Auth. Why not verify it during Auth? emmm... Spitting blood.

ArgumentResolver

The parameter parser is a tool provided by spring for parsing custom parameters. Our commonly used @ RequestParam annotation has its shadow. Using it, we can combine the parameters into what we want before entering the Controller Action. Spring will maintain a ResolverList. When the request arrives, spring finds that there are custom type parameters (non basic types), and will try these resolvers in turn until a Resolver can resolve the required parameters. To implement a parameter Resolver, you need to implement the HandlerMethodArgumentResolver interface.

realization

  1. Define the user-defined parameter type {AuthParam, and there are appkey related fields in the class;
  2. Define AuthParamResolver and implement HandlerMethodArgumentResolver interface;
  3. Implement the {supportsParameter() interface method to adapt AuthParam to AuthParamResolver;
  4. Implement the resolveArgument() interface method to parse the reqest object to generate the AuthParam object, and verify the AuthParam here to confirm whether the appkey is in the white list;
  5. Add AuthParam parameter in the signature on the Controller Action method to enable this Resolver;

The AuthParamResolver class implemented is as follows:

@Component
public class AuthParamResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(AuthParam.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        Whitelist whitelist = parameter.getMethodAnnotation(Whitelist.class);
        //Verify the whitelist through webRequest and whitelist
        return new AuthParam();
    }
}

extend

Of course, the parameter parser also needs to be configured separately. We also configure it in WebMvcConfigurerAdapter:

@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new AuthParamResolver());
    }
}

After this implementation, I was still a little worried, so I searched the Internet to see if there were other ways to realize this function, and found that the common one was Filter.

Filter

Filter is not provided by Spring. It is defined in the Servlet specification and supported by the Servlet container. Requests filtered by the filter will not be sent to the Spring container. Its implementation is also relatively simple. It implements javax Servlet. Filter interface. Because it is not in the Spring container, the filter cannot obtain the resources of the Spring container. It can only use the ServletRequest and ServletResponse of native Java to obtain the request parameters. In addition, the doFilter method calling FilterChain should be displayed in a filter, otherwise the request is considered to be intercepted. The implementation is similar to:

public class WhitelistFilter implements javax.servlet.Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
  //Called once after initialization
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
     //Determine whether interception is required
       chain.doFilter(request, response); //The request passes the call to be displayed
    }

    @Override
    public void destroy() {
     //Called once when destroyed
    }
}

extend

Filter also needs to display configuration:

@Configuration
public class FilterConfiguration {

    @Bean
    public FilterRegistrationBean someFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new WhitelistFilter());
        registration.addUrlPatterns("/*");
        registration.setName("whitelistFilter");
        registration.setOrder(1); //Sets the order in which filters are called
        return registration;
    }
}

Summary

The four implementation methods have their own suitable scenarios, so what is the call order between them? Filter is implemented by Servlet. Naturally, it is called first, and the Interceptor called later is intercepted. Naturally, it does not need to be processed later, then the parameter parser, and finally the tangent point of the section.

Two original springboot+Vue projects are recommended, with complete video explanations, documents and source code:

[VueAdmin] teach you how to develop the front and back end separated background management system of SpringBoot+Jwt+Vue

[VueBlog] complete teaching of front and back end separation blog project developed based on SpringBoot+Vue

If you have any questions, come to my official account. Java Q & A ]Ask me

Keywords: Spring Boot Annotation

Added by cparekh on Fri, 31 Dec 2021 04:52:17 +0200