SpringMVC接口权限拦截器的实现

背景

       每个网站都会和其它的公司或者平台有对接,有的公司内部的也会有接口的相互调用。但是接口的直接开放并不安全,必须有对应的令牌才能保证安全。令牌在什么时候去校验?自然是请求过来时,后端接收前。

       Javaweb开发有专门处理这种请求的模块—拦截器。拦截器会在校验请求是否符合规则,符合才能真正被接收。那么只要在拦截器中校验令牌是否正确就能过滤掉非法的请求。甚至通过控制令牌的权限控制访问权限。

原理

       interceptor提供了preHandle和postHandle以及afterCompletion三个方法。preHandle调用controller具体方法之前调用,postHandle完成具体方法之后调用,afterCompletion完成对页面的render以后调用,至此整个页面渲染完成。也就是说我们在preHandle记录开始的时间,在afterCompletion记录结束的时间,就可或者整个页面生成的时间。

       很显然,我们这次需要拦截的是接口权限。有权限的才能做后续的操作,那就是使用preHandle方法。

步骤和流程

步骤:

第一步:自定义一个实现了Interceptor接口的类,或者继承抽象类AbstractInterceptor。这里继承了HandlerInterceptor接口
    第二步:在配置文件中注册定义的拦截器。
    第三步:在需要使用Controller中编写业务逻辑

流程:

具体实现

1 自定义拦截器类,实现HandlerInterceptor接口

2 实现preHandle方法,此处校验的是app_id和app_secret是否合法

3 在configuration类中注册拦截器,定义生效的规则

4 编写Controller代码

核心代码

拦截器OpenIntercept:

@Component	//表示这是一个组件,可以实现依赖注入
public class OpenIntercept  implements HandlerInterceptor{	
	// 校验的数据存在数据库中,需要查询数据库
	@Autowired
	AppSourceMapper appSourceMapper; 
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// 获取指定的参数数据,用于校验使用
		String app_id = request.getParameter("app_id");
		String app_secret = request.getParameter("app_secret");
		System.out.println(request.getRemoteAddr());
		// 校验是否合法
		if(StringUtils.isNotBlank(app_id)&& StringUtils.isNotBlank(app_secret)&& checkAppSourceIsExsist(app_id,app_secret)){
			return true;	//合法通过
		} else{
			//非法给出提示
			response.setCharacterEncoding("UTF-8");
			response.getOutputStream().write(ResultUtils.error(-1, "您无操作此接口的权限!").getBytes());
			return false;
		}
	}
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
	}
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
	}
	// 校验数据库是否存在令牌对
	private boolean checkAppSourceIsExsist(String app_id,String app_secret){
		return  appSourceMapper.countByAppIdAndSecret(app_id, app_secret)>0?true:false;
	}
}

 

配置类CoreConfiguration 

public class CoreConfiguration extends WebMvcConfigurerAdapter{
	@Autowired
	OpenIntercept openIntercept; 
    // 注册拦截器
	public void addInterceptors(InterceptorRegistry registry) {
        // 注册包括拦截器和拦截的路径,可以使用统配表达式
		registry.addInterceptor(openIntercept).addPathPatterns("/open/**");
	 }
    @Bean
    public HttpMessageConverter<String> responseBodyConverter() {
        StringHttpMessageConverter converter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        return converter;
    }
    @Override
    public void configureMessageConverters(
            List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        converters.add(responseBodyConverter());
    }
    @Override
    public void configureContentNegotiation(
            ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
    }
}

    觉得本文好的可以点个赞,觉得不好的可以提提建议或意见,一起进步,一起成长!!!

    欢迎邮件来信讨论 [email protected]

猜你喜欢

转载自my.oschina.net/wxdl/blog/1630368