最近用到一种前端模板技术:vue,在权限控制上没有用springSecurity。因此用拦截器和注解结合实现了权限控制。
实现如下:
- /**
- * @author blueriver
- * @description 权限常量
- * @date 2017/11/17
- * @since 1.0
- */
- public class PermissionConstants {
- /**
- * 管理员-产品列表查询
- */
- public static final String ADMIN_PRODUCT_LIST = "admin_product_list";
- /**
- * 管理员-产品详情
- */
- public static final String ADMIN_PRODUCT_DETAIL = "admin_product_detail";
- }
权限也可以不定义为常量,看项目情况
- /**
- * @author blueriver
- * @description 与拦截器结合使用 验证权限
- * @date 2017/11/17
- * @since 1.0
- */
- @Target({ElementType.TYPE, ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- @Inherited
- @Documented
- public @interface RequiredPermission {
- String value();
- }
ElementType.TYPE,ElementType.METHOD表示注解可以标记类和方法
- /**
- * @author blueriver
- * @description 权限拦截器
- * @date 2017/11/17
- * @since 1.0
- */
- public class SecurityInterceptor implements HandlerInterceptor {
- @Autowired
- private AdminUserService adminUserService;
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- // 验证权限
- if (this.hasPermission(handler)) {
- return true;
- }
- // null == request.getHeader("x-requested-with") TODO 暂时用这个来判断是否为ajax请求
- // 如果没有权限 则抛403异常 springboot会处理,跳转到 /error/403 页面
- response.sendError(HttpStatus.FORBIDDEN.value(), "无权限");
- return false;
- }
- /**
- * 是否有权限
- *
- * @param handler
- * @return
- */
- private boolean hasPermission(Object handler) {
- if (handler instanceof HandlerMethod) {
- HandlerMethod handlerMethod = (HandlerMethod) handler;
- // 获取方法上的注解
- RequiredPermission requiredPermission = handlerMethod.getMethod().getAnnotation(RequiredPermission.class);
- // 如果方法上的注解为空 则获取类的注解
- if (requiredPermission == null) {
- requiredPermission = handlerMethod.getMethod().getDeclaringClass().getAnnotation(RequiredPermission.class);
- }
- // 如果标记了注解,则判断权限
- if (requiredPermission != null && StringUtils.isNotBlank(requiredPermission.value())) {
- // redis或数据库 中获取该用户的权限信息 并判断是否有权限
- Set<String> permissionSet = adminUserService.getPermissionSet();
- if (CollectionUtils.isEmpty(permissionSet) ){
- return false;
- }
- return permissionSet.contains(requiredPermission.value());
- }
- }
- return true;
- }
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- // TODO
- }
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- // TODO
- }
- }
- @Configuration
- public class MVCConfig extends WebMvcConfigurerAdapter {
- @Bean
- public SecurityInterceptor securityInterceptor() {
- return new SecurityInterceptor();
- }
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(securityInterceptor()).excludePathPatterns("/static/*")
- .excludePathPatterns("/error").addPathPatterns("/**");
- }
- }
springboot中注入拦截器
这里说一下多拦截器的配置方式
最后强调一点:只有经过DispatcherServlet 的请求,才会走拦截器链,我们自定义的Servlet 请求是不会被拦截的,比如我们自定义的Servlet地址 http://localhost:8080/xs/myservlet 是不会被拦截器拦截的。并且不管是属于哪个Servlet 只要复合过滤器的过滤规则,过滤器都会拦截。
最后说明下,我们上面用到的 WebMvcConfigurerAdapter 并非只是注册添加拦截器使用,其顾名思义是做Web配置用的,它还可以有很多其他作用,通过下面截图便可以大概了解,具体每个方法都是干什么用的,留给大家自己研究(其实都大同小异也很简单)。
- /**
- * @author blueriver
- * @description 产品管理
- * @date 2017/10/25
- * @since 1.0
- */
- @Controller
- @RequestMapping("/product")
- // @PermissionConstants.ADMIN_PRODUCT_MANAGEMENT
- public class ProductController {
- /**
- * 产品列表
- *
- * @return
- */
- @RequestMapping("/list")
- @RequiredPermission(PermissionConstants.ADMIN_PRODUCT_LIST) // 权限注解
- public String list() {
- // 省略产品列表查询逻辑
- return "/product/list";
- }
- /**
- * 产品详情
- *
- * @return
- */
- @RequestMapping("/detail")
- @RequiredPermission(PermissionConstants.ADMIN_PRODUCT_DETAIL) // 权限注解
- public String detail() {
- // 省略查询产品详情的逻辑
- return "/product/edit";
- }
- /**
- * 删除产品
- *
- * @return
- */
- @RequestMapping("/delete")
- public String delete() {
- // 省略删除产品的逻辑
- return "/product/list";
- }
- }
- 如果没有标记权限注解,则不会验证该请求的权限,如/product/delete 请求
联系客服