在实际项目中很多时候我们会用到拦截器,来拦截请求,在请求之前、之后做一些业务需求的操作。最近公司对安全操作提出了需求。防止匿名发送恶意请求,要求在用户发送请求之前做用户认证,如果没有认证通过则不予许发送请求。这个需求拿Shiro这种权限框架请示很好实现,Shiro在用户登录之前,登陆之后都做了完善的认证和授权操作。在用户登录之前首先会进行认证操作,如果没有通过会让其登录,其实,应该也是Shiro自己封装的拦截器,拦截请求,判断是否带有认证信息。扒开源码可以看出,
如下图:
因为架构原因,所以我暂时没有使用Shiro权限框架,具体实现大致和Shiro框架思想差不多,在请求之前,首先进行认证,认证通过以后放行,认证失败,跳转错误界面。
前提:请求携带用户登录token(有时效周期,会失效),用户的username,两者均可以放在请求头中
方法:拦截器 preHandle方法,获取token及username,调用Dao层方法,用user对象与token进行比对认证
结果:认证通过,请求方形,失败跳转失败界面。
这时候遇到一个问题,在Spring的依赖注入,将对象交给Spring的容器管理,然后当我们需要调用的时候,直接从Spring容器中取得。但是拦截器拦截请求,在Spring的上下文之前,也就是这时候容器中并没有Dao层这个对象。所以如果我们不做处理直接调用的话,会抛出空指针的异常。所以,我们首先考虑如何将对象注入到Spring的容器中。这时候就需要下面的方法。
创建一个配置类对象实现WebMvcConfigurer接口,将自己定义的拦截器对象注入Bean中,完成以上配置,我们就可以在拦截器中调用你需要的Service 或者 Dao层方法了。
之后我们获取到username,token之后,就可以调用Dao层方法,获取对象,调用tokenUtils方法进行认证了。大致如上图。
在写方法的时候,我遇到一个坑,就是拦截器拦截请求的时候,会拦截两次,以至于第一次对象注入成功,但是第二次失败就会抛出空指针异常,后来查了博客才了解到。
在配置拦截器的时候,如果写的是 "/**",就会连续调用两次,改成"/*",就不会出现这种情况了。这个坑,记录一下。
以上就是大致流程和方法,以及采坑记录。