SpringBoot中如何进行鉴权呢?
下文笔者讲述SpringBoot实现鉴权的四种方法分享,如下所示
SpringBoot实现鉴权的实现思路
方式1: AOP 方式2: 继承 Interceptor接口,编写拦截器 方式3: 继承ArgumentResolver的方式 方式4; 编写Filter例:AOP
使用@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.java265.Whitelist)") public void whitelistPointCut() { } } ======只需在Controller上添加 @Whitelist 即可实现相应的拦截
方式2:Interceptor拦截器
Spring拦截器(Interceptor) 拦截器用于在 Controller 内 Action 被执行前通过一些参数判断是否要执行此方法,要实现一个拦截器 可以实现 Spring 的 HandlerInterceptor 接口。例:
@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视图渲染完成后执行 } } //启用拦截器还要显式配置它启用 //使用WebMvcConfigurerAdapter对它进行配置 @Configuration public class MvcConfiguration extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new WhitelistInterceptor()).addPathPatterns("/*").order(1); // 这里可以配置拦截器启用的 path 的顺序,在有多个拦截器存在时,任一拦截器返回 false 都会使后续的请求方法不再执行 } }
ArgumentResolver
参数解析器: 是Spring提供的用于解析自定义参数的工具 我们常用 @RequestParam 注解就有它的影子 使用它 我们可以将参数在进入Controller Action之前就组合成我们想要的样子 Spring 会维护一个ResolverList 当请求到达时 Spring发现有自定义类型参数(非基本类型) 会依次尝试这些Resolver 直到有一个Resolver能解析需要的参数 要实现一个参数解析器 需要实现HandlerMethodArgumentResolver 接口。
实现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(); } } //配置WebMvcConfigurerAdapter内配置 @Configuration public class MvcConfiguration extends WebMvcConfigurerAdapter { @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { argumentResolvers.add(new AuthParamResolver()); } }
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; } }
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。