文章介绍了spring-boot中完成通用auth的四种方法,包罗 传统AOP、阻拦器、参数剖析器和过滤器,并提供了对应的实例代码,最初复杂总结了下他们的实行次序。
媒介
近来不停被无尽的商业需求吞没,没工夫喘气,终于接到一个能让我打破代码安宁区的活儿,办理它的历程十分迂回,一度让我猜疑人生,不外劳绩也很大,代码方面不分明,但觉得本人抹失了 java、Tomcat、Spring 不停挡在我面前目今的一层纱。对它们的了解上了一个新的条理。
很久没输入了,于是挑一个方面总结一下,盼望在梳理历程中再理解一些其他的工具。由于 Java 昌盛的生态,上面每一个模块都有少量的文章专门报告。以是我选了别的一个角度,从实践题目动身,将这些疏散的知识串联起来,列位可以作为一个综述来看。各个模块的极致细致介绍,各人可以去翻官方文档或看网络上的其他博客。
需求很复杂明晰,跟产品们提的妖艳需求一点也纷歧样:在ag九游会的 web 框架里添加一个通用
的 appkey 白名单校验功效,盼望它的扩展性更好一些。
这个 web 框架是部分先驱者基于 spring-boot 完成的,介于商业和 Spring 框架之间,做一些倾向于商业的通用性功效,如 日记输入、功效开关、通用参数剖析等。寻常是对商业通明的,近来不停忙于把需求做好,代码写好,乃至从没留意过它的存在。
传统AOP
关于这种需求,起首想到确当然是 Spring-boot 提供的 AOP 接口,只必要在 Controller 办法前添加切点,然后再对切点举行处置即可。
完成
其利用步调如下:
利用@Aspect
声明一下切面类WhitelistAspect
;
在切面类内添加一个切点whitelistPointcut()
,为了完成此切点机动可拆卸的才能,这里不利用execution
所有阻拦,而是添加一个表明@Whitelist
,被表明的办法才会校验白名单。
在切面类中利用 spring 的 AOP 表明@Before
声明一个关照办法checkWhitelist()
在 Controller 办法被实行之前校验白名单。
切面类伪代码如下
@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
表明完成功效。
扩展
本例中利用了 表明 来声明切点,而且我完成了经过表明参数来声明要校验的白名单,假如之后还必要添加其他白名单的话,如经过 UID 来校验,则可以为此表明添加uid()
等办法,完成自界说校验。
别的,spring 的 AOP 还支持execution(实行办法) 、bean(婚配特命名称的 Bean 工具的实行办法)
等切点声明办法和@Around(在目的函数实行中实行) 、@After(办法实行后)
等关照办法。
云云,功效曾经完成了,但向导并不得意=_=,缘故原由是项目中 AOP 用得太多了,都用滥了,发起我换一种方法。嗯,只好搞起。
Interceptor
Spring 的 阻拦器(Interceptor) 完成这个功效也十分符合。望文生义[wàng wén shēng yì],阻拦器用于在 Controller 内 Action 被实行前经过一些参数判别能否要实行此办法,要完成一个阻拦器,可以完成 Spring 的HandlerInterceptor
接口。
完成
完成步调如下:
界说阻拦器类AppkeyInterceptor
类并完成 HandlerInterceptor 接口。
完成其preHandle()
办法;
在 preHandle 办法内经过表明和参数判别能否必要阻拦哀求,阻拦哀求时接口前往false
;
在自界说的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视图渲染完成后实行
}
}
要启用 阻拦器还要显式设置装备摆设它启用,这里ag九游会利用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
,但呼应数据为空。
当利用阻拦器完成功效后,向导终于祭出大招了:ag九游会曾经有一个 Auth 参数了,appkey 可以从 Auth 参数里取到,可以把在不在白名单作为 Auth 的一种方法,为什么不在 Auth 时校验?emmm… 吐血中。
ArgumentResolver
参数剖析器是 Spring 提供的用于剖析自界说参数的东西,ag九游会常用的@RequestParam
表明就有它的影子,利用它,ag九游会可以将参数在进入Controller Action之前就组分解ag九游会想要的样子。Spring 会维护一个ResolverList
, 在哀求抵达时,Spring 发明有自界说范例参数(非根本范例), 会顺次实验这些 Resolver,直到有一个 Resolver 能剖析必要的参数。要完成一个参数剖析器,必要完成HandlerMethodArgumentResolver
接口。
完成
界说自界说参数范例AuthParam
,类内有 appkey 相干字段;
界说AuthParamResolver
并完成 HandlerMethodArgumentResolver 接口;
完成supportsParameter()
接口办法将 AuthParam 与 AuthParamResolver 适配起来;
完成resolveArgument()
接口办法剖析 reqest 工具天生 AuthParam 工具,并在此校验 AuthParam ,确认 appkey 能否在白名单内;
在 Controller Action 办法上署名内添加 AuthParam 参数以启用此 Resolver;
完成的 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();
}
}
固然,利用参数剖析器也必要独自设置装备摆设,ag九游会异样在WebMvcConfigurerAdapter
内设置装备摆设:
@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List 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;
}
}
四种完成方法都有其合适的场景,那么它们之间的挪用次序怎样呢?
Filter 是 Servlet 完成的,天然是开始被挪用,后续被挪用的是 Interceptor 被阻拦了天然不必要后续再举行处置,然后是 参数剖析器,最初才是 切面的切点。我将四种方法在一个项目内所有完成后,输入日记也证明白这个结论。
你另有什么想要增补的吗?
PS:接待在留言区留下你的看法,一同讨论进步。假如明天的文章让你有新的启示,接待转发分享给更多人。
版权声明:内容泉源网络,版权归原创者一切。除非无法确认,ag九游会都市标明作者及来由,若有侵权烦请见告,ag九游会会立刻删除并表现歉意。谢谢!
接待参加后端架构师,在背景复兴“”即可。
近来口试BAT,整理一份口试材料《Java口试BAT通关手册》,掩盖了Java中心技能、JVM、Java并发、SSM、微办事、数据库、数据布局等等。在这里,我为各人预备了一份2021年最新最全BAT等大厂Java口试履历总结。