>  기사  >  Java  >  Springboot가 범용 인증 인증을 구현하는 방법

Springboot가 범용 인증 인증을 구현하는 방법

王林
王林앞으로
2023-05-14 11:31:051121검색

Traditional AOP

이 요구사항에 대해 가장 먼저 떠오르는 것은 당연히 Spring-boot에서 제공하는 AOP 인터페이스입니다. Controller 메소드 앞에 포인트컷을 추가한 다음 포인트컷을 처리하면 됩니다.

implementation

단계는 다음과 같습니다.

  1. 애스펙트 클래스 WhitelistAspect를 선언하려면 @Aspect를 사용하세요.

  2. 이 포인트 컷을 구현하려면 컷 포인트 whitelistPointcut()을 추가하세요. 즉, 모든 실행을 가로채는 대신 유연하고 조립할 수 있는 능력입니다. @Whitelist 주석을 추가하면 주석이 달린 메서드만 화이트리스트를 확인합니다.

  3. 관측 클래스에서 spring의 AOP 주석 @Before를 사용하여 Controller 메서드가 실행되기 전에 화이트리스트를 확인하는 알림 메서드 checkWhitelist()를 선언합니다.

Aspect 클래스의 의사 코드는 다음과 같습니다.

 @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() {
    }
  }

Controller 메서드에 @Whitelist 주석을 추가하여 함수를 구현합니다.

Extension

이 예제에서는 어노테이션을 사용하여 포인트컷을 선언하고, 검증할 화이트리스트를 선언하기 위해 어노테이션 매개변수를 구현했습니다. UID를 통한 검증 등 나중에 다른 화이트리스트를 추가해야 하는 경우, 다음과 같은 메소드를 추가할 수 있습니다. 맞춤 확인을 구현하려면 이 주석에 uid()를 사용하세요.

이외에도 spring의 AOP는 실행(실행 방법), bean(특정 이름과 일치하는 Bean 객체의 실행 방법) 및 기타 포인트컷 선언 방법과 @Around(대상 함수 실행 시 실행), @After( 메소드 실행(이후) 및 기타 알림 메소드.

그래서 기능을 구현했지만 리더가 만족하지 않습니다 =_=. 그 이유는 AOP가 프로젝트에서 너무 많이 사용되고 남용되었기 때문입니다. 글쎄요, 이제 시작해야만 했어요. 또한 주목하세요: Ma Yuan Technology 칼럼, 백그라운드 답변: "인터뷰 가이드"를 얻을 수 있습니다. 최신 버전의 고화질 PDF 3625 페이지의 주요 인터넷 회사 인터뷰 질문입니다.

Interceptor

Spring의 Interceptor도 이 기능을 구현하는 데 매우 적합합니다. 이름에서 알 수 있듯이 인터셉터는 컨트롤러의 Action이 실행되기 전에 일부 매개변수를 통해 이 메서드를 실행할지 여부를 결정하는 데 사용됩니다. 인터셉터를 구현하려면 Spring의 HandlerInterceptor 인터페이스를 구현할 수 있습니다.

Implementation

구현 단계는 다음과 같습니다.

  1. 인터셉터 클래스 AppkeyInterceptor 클래스를 정의하고 HandlerInterceptor 인터페이스를 구현합니다.

  2. preHandle() 메소드를 구현합니다.

  3. 요청을 차단해야 하는지 여부를 결정하려면 preHandle 메소드에 주석과 매개변수를 사용하세요.

  4. 이 차단을 등록하세요. 사용자 정의 WebMvcConfigurerAdapter 클래스에서

AppkeyInterceptor 클래스는 다음과 같습니다.

@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

인터셉터를 활성화하려면 여기에서 WebMvcConfigurerAdapter를 사용하여 명시적으로 구성해야 합니다. 이를 상속하는 MvcConfiguration은 ComponentScan 경로에 있어야 합니다.

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

또한 인터셉터가 성공적으로 실행된 후 응답 코드는 200이지만 응답 데이터는 비어 있습니다.
인터셉터를 사용하여 기능을 구현한 후 리더는 마침내 큰 조치를 취했습니다. 인증 매개변수에서 앱 키를 얻을 수 있습니다. 인증 방법으로 화이트리스트를 사용할 수 있습니다. ? 시간 확인? 음... 피를 토하는군요.

ArgumentResolver

매개변수 파서는 사용자 정의 매개변수를 구문 분석하기 위해 Spring에서 제공하는 도구입니다. 일반적으로 사용되는 @RequestParam 주석을 사용하면 원하는 방식으로 매개변수를 결합할 수 있습니다. 그것. Spring은 ResolverList를 유지 관리합니다. 요청이 도착하면 Spring은 사용자 정의 유형 매개변수(비기본 유형)가 있음을 발견하고 Resolver가 필요한 매개변수를 구문 분석할 수 있을 때까지 이러한 Resolver를 순서대로 시도합니다. 매개변수 해석기를 구현하려면 HandlerMethodArgumentResolver 인터페이스를 구현해야 합니다.

implementation

  • 사용자 정의 매개변수 유형 AuthParam을 정의하고, 클래스에 appkey 관련 필드가 있습니다.

  • AuthParamResolver를 정의하고 HandlerMethodArgumentResolver 인터페이스를 구현합니다. 결합하다 AuthParamResolver가 포함된 AuthParam은 ;

  • reqest 객체를 구문 분석하여 AuthParam 객체를 생성하는 reqestArgument() 인터페이스 메서드를 구현하고 여기에서 AuthParam을 확인하여 앱 키가 화이트리스트에 있는지 확인합니다.

  • AuthParam 매개변수 추가

  • 구현된 AuthParamResolver 클래스는 다음과 같습니다.

  • @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();
        }
    }
Extension


물론 매개변수 파서를 사용하는 경우에도 별도로 구성해야 합니다. WebMvcConfigurerAdapter에 있습니다:


@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {

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

이번 구현이 완료되었지만 아직 걱정되는 부분이 있어서 이 기능을 구현하는 다른 방법이 있는지 온라인으로 검색해 본 결과 Filter도 일반적인 방법이라는 것을 알게 되었습니다.


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;
    }
}

위 내용은 Springboot가 범용 인증 인증을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제