Heim  >  Artikel  >  Java  >  Wie Springboot die universelle Auth-Authentifizierung implementiert

Wie Springboot die universelle Auth-Authentifizierung implementiert

王林
王林nach vorne
2023-05-14 11:31:051121Durchsuche

Traditionelles AOP

Für diese Anforderung fällt mir natürlich als Erstes die von Spring-Boot bereitgestellte AOP-Schnittstelle ein. Sie müssen nur einen Pointcut vor der Controller-Methode hinzufügen und dann den Pointcut verarbeiten.

Implementierung

Die Schritte sind wie folgt:

  1. Verwenden Sie @Aspect, um die Aspektklasse WhitelistAspect zu deklarieren;

  2. Fügen Sie einen Schnittpunkt WhitelistPointcut() in der Aspektklasse hinzu Punkt, es ist flexibel und kann zusammengestellt werden. Anstatt hier alle Ausführungen abzufangen, fügen Sie eine Annotation @Whitelist hinzu, und nur die annotierte Methode überprüft die Whitelist.

  3. Verwenden Sie die AOP-Annotation @Before von Spring in der Aspektklasse, um eine Benachrichtigungsmethode checkWhitelist() zu deklarieren, um die Whitelist zu überprüfen, bevor die Controller-Methode ausgeführt wird.

Der Pseudocode der Aspektklasse lautet wie folgt:

 @Aspect
  public class WhitelistAspect {

    @Before(value = "whitelistPointcut() && @annotation(whitelist)")
    public void checkAppkeyWhitelist(JoinPoint joinPoint, Whitelist whitelist) {
        checkWhitelist();
        // 可使用 joinPoint.getArgs() 获取Controller方法的参数
        // 可以使用 whitelist 变量获取注解参数
    }

    @Pointcut("@annotation(com.zhenbianshu.Whitelist)")
    public void whitelistPointCut() {
    }
  }

Fügen Sie die @Whitelist-Annotation zur Controller-Methode hinzu, um die Funktion zu implementieren.

Erweiterung

In diesem Beispiel werden Annotationen zum Deklarieren von Pointcuts verwendet, und ich habe Annotationsparameter implementiert, um die zu überprüfende Whitelist zu deklarieren. Wenn später andere Whitelists hinzugefügt werden müssen, z. B. die Überprüfung über UID, können Sie Methoden wie hinzufügen als uid() zu dieser Annotation hinzufügen, um eine benutzerdefinierte Überprüfung zu implementieren.

Darüber hinaus unterstützt das AOP von Spring auch die Ausführung (Ausführungsmethode), Bean (Ausführungsmethode eines Bean-Objekts, das einem bestimmten Namen entspricht) und andere Pointcut-Deklarationsmethoden sowie @Around (wird bei der Ausführung der Zielfunktion ausgeführt), @After ( Methodenausführung (nachher) und andere Benachrichtigungsmethoden.

Die Funktion wurde also implementiert, aber der Leiter ist nicht zufrieden =_= Der Grund dafür ist, dass AOP im Projekt zu häufig verwendet und missbraucht wurde. Nun, ich musste einfach damit anfangen. Beachten Sie auch: Ma Yuan Technology Column, Antwort im Hintergrund: „Interview Guide“ ist erhältlich, die neueste Version von hochauflösenden PDF-Interviewfragen mit 3625 Seiten für große Internetunternehmen.

Interceptor

Springs Interceptor eignet sich auch sehr gut zur Implementierung dieser Funktion. Wie der Name schon sagt, wird der Interceptor verwendet, um über einige Parameter zu bestimmen, ob diese Methode ausgeführt werden soll, bevor die Aktion im Controller ausgeführt wird. Um einen Interceptor zu implementieren, können Sie die HandlerInterceptor-Schnittstelle von Spring implementieren.

Implementierung

Die Implementierungsschritte lauten wie folgt:

  1. Definieren Sie die Interceptor-Klasse AppkeyInterceptor und implementieren Sie die HandlerInterceptor-Schnittstelle.

  2. Implementieren Sie die preHandle-Methode.

  3. Verwenden Sie Anmerkungen und Parameter in der preHandle-Methode, um zu bestimmen, ob die Anforderung abgefangen werden muss.

  4. Registrieren Sie dieses Abfangen In der benutzerdefinierten WebMvcConfigurerAdapter-Klasse lautet die

AppkeyInterceptor-Klasse wie folgt:

@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(); 通过 request 获取请求参数,通过 whitelist 变量获取注解参数
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  // 方法在Controller方法执行结束后执行
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  // 在view视图渲染完成后执行
    }
}

Extension

Um den Interceptor zu aktivieren, müssen Sie ihn auch explizit konfigurieren. Hier verwenden wir WebMvcConfigurerAdapter, um ihn zu konfigurieren. Es ist zu beachten, dass sich die MvcConfiguration, die sie erbt, im ComponentScan-Pfad befinden muss.

@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new WhitelistInterceptor()).addPathPatterns("/*").order(1);
        // 这里可以配置拦截器启用的 path 的顺序,在有多个拦截器存在时,任一拦截器返回 false 都会使后续的请求方法不再执行
    }
}

Beachten Sie außerdem, dass nach erfolgreicher Ausführung des Interceptors der Antwortcode 200 lautet, die Antwortdaten jedoch leer sind.
Nachdem der Anführer den Interceptor verwendet hat, hat er sich schließlich einen großen Schritt ausgedacht: Wir haben bereits einen Auth-Parameter. Wir können Whitelisting als Methode für Auth verwenden ? Zeitüberprüfung? Emmm... Blut erbrechen.

ArgumentResolver

Der Parameter-Parser ist ein von Spring bereitgestelltes Tool zum Parsen benutzerdefinierter Parameter. Mit ihm können wir die Parameter in unserer gewünschten Weise kombinieren Es. Spring verwaltet eine ResolverList. Wenn die Anforderung eintrifft, stellt Spring fest, dass benutzerdefinierte Typparameter (nicht grundlegende Typen) vorhanden sind, und testet diese Resolver nacheinander, bis ein Resolver die erforderlichen Parameter analysieren kann. Um einen Parameter-Resolver zu implementieren, müssen Sie die HandlerMethodArgumentResolver-Schnittstelle implementieren.

Implementierung

  • Definieren Sie den benutzerdefinierten Parametertyp AuthParam, und es gibt appkey-bezogene Felder in der Klasse;

  • Definieren Sie AuthParamResolver und implementieren Sie die Schnittstelle „HandlerMethodArgumentResolver“. kombinieren AuthParam mit AuthParamResolver passt sich an ;

  • Implementieren Sie die Schnittstellenmethode „resolveArgument()“, um das Anforderungsobjekt zu analysieren, um ein AuthParam-Objekt zu generieren, und überprüfen Sie hier AuthParam, um zu bestätigen, ob sich der Appkey in der Whitelist befindet;

  • Fügen Sie den AuthParam-Parameter hinzu in der Signatur der Controller-Aktionsmethode, um diesen Resolver zu aktivieren es im WebMvcConfigurerAdapter:

  • @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);
            // 通过 webRequest 和 whitelist 校验白名单
            return new AuthParam();
        }
    }
  • Dieses Mal ist die Implementierung abgeschlossen, ich habe immer noch einige Bedenken, also habe ich online gesucht, ob es andere Möglichkeiten gibt, diese Funktion zu erreichen, und festgestellt, dass Filter auch häufig vorkommt.

    Filter

    Filter 并不是 Spring 提供的,它是在 Servlet 规范中定义的,是 Servlet 容器支持的。被 Filter 过滤的请求,不会派发到 Spring 容器中。它的实现也比较简单,实现 javax.servlet.Filter接口即可。

    由于不在 Spring 容器中,Filter 获取不到 Spring 容器的资源,只能使用原生 Java 的 ServletRequest 和 ServletResponse 来获取请求参数。

    另外,在一个 Filter 中要显示调用 FilterChain 的 doFilter 方法,不然认为请求被拦截。实现类似:
    public class WhitelistFilter implements javax.servlet.Filter {

    @Override
        public void init(FilterConfig filterConfig) throws ServletException {
      // 初始化后被调用一次
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
         // 判断是否需要拦截
           chain.doFilter(request, response); // 请求通过要显示调用
        }
    
        @Override
        public void destroy() {
         // 被销毁时调用一次
        }
    }

    扩展

    Filter 也需要显示配置:

    @Configuration
    public class FilterConfiguration {
    
        @Bean
        public FilterRegistrationBean someFilterRegistration() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(new WhitelistFilter());
            registration.addUrlPatterns("/*");
            registration.setName("whitelistFilter");
            registration.setOrder(1); // 设置过滤器被调用的顺序
            return registration;
        }
    }

Das obige ist der detaillierte Inhalt vonWie Springboot die universelle Auth-Authentifizierung implementiert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen