一、创建自定义注解
package com.shenlan.common.annotation;
import java.lang.annotation.*;
/**
* @author : xukun
* @date : 2020/9/17
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface RequestAuthority {
String[] value();
//所有的权限都满足,默认为false,表示满足一个就可以
boolean andAuthority() default false;
}
二、在控制器的方法上使用该注解
@PostMapping("/search")
@ResponseBody
@ApiOperation(value = "查询或检索图层列表")
//这些权限只需要满足一个就可以
@RequestAuthority(value = {AuthorityConstant.INDEX_LAYER_QUERY, AuthorityConstant.LAYER_LIST,
AuthorityConstant.LAYER_QUERY, AuthorityConstant.RELATIONWITHLAYER_QUERY,
AuthorityConstant.RELATION_QUERY, AuthorityConstant.RELATION_LAYER_QUERY,
AuthorityConstant.LAYER_APPROVAL_LAYER_LIST, AuthorityConstant.LAYER_APPROVAL_LAYER_QUERY
})
public ResponseData search(@RequestParam(defaultValue = "1") int pageNo,
@RequestParam(defaultValue = "10") int pageSize, @RequestBody LayerSearchPO params) {
PageHelper.startPage(pageNo, pageSize);
return ResponseDataUtil.buildSuccess(new PageInfo<>(service.list(params)));
}
三、创建自定义拦截器,继承
HandlerInterceptorAdapter
,重写preHandle
方法,那么所有的请求在进入控制器前都会被该方法拦截
。我们在这个方法里面进行权限的认证。
/**
* @author : xukun
* @date : 2020/9/21
*/
public class SecurityInterceptor extends HandlerInterceptorAdapter {
@Autowired
UserInfoService userInfoService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!isAuthority(handler)) {
throw new BDException("没有操作权限");
}
return true;
}
/**
* 判断此次请求是否有权限
*
* @param handler
* @return 有权限返回true
*/
private boolean isAuthority(Object handler) {
boolean flag = true;
if (handler instanceof HandlerMethod) {
//获得请求的方法
Method method = ((HandlerMethod) handler).getMethod();
//获得该方法上面的注解,如果没有注解,直接返回true,通过
RequestAuthority annotation = method.getAnnotation(RequestAuthority.class);
if (annotation != null) {
//得到当前登录人的权限,判断请求的权限是否包含在内
QueryUserAuthRequest request = new QueryUserAuthRequest();
request.setUserId(UserUtils.getLogInfo().getId());
request.setAppCode(Long.valueOf(SysConstant.appCode));
List<String> authorlist;
try {
authorlist = userInfoService.getAuthorByUserId(request).getData();
} catch (RestTemplateException e) {
throw new BDException(e.getMessage());
}
//获得注解的值(权限)
String[] values = annotation.value();
//是否所有的权限都满足才可以
boolean andAuthority = annotation.andAuthority();
if (andAuthority) {//该请求所有的权限都满足才可以
flag = containsCheck(Arrays.asList(values), authorlist);
} else {
flag = haveCheck(Arrays.asList(values), authorlist);
}
}
}
return flag;
}
/**
* 判断权限列表中是否包含给定权限
*
* @param targets 给定权限
* @param sources 权限列表
* @return 全部包含返回true
*/
private boolean containsCheck(List<String> targets, List<String> sources) {
if (targets == null || sources == null || targets.size() > sources.size()) {
return false;
}
for (String target : targets) {
if (!sources.contains(target)) {
return false;
}
}
return true;
}
/**
* 判断权限列表中是否有给定权限
*
* @param targets 给定权限
* @param sources 权限列表
* @return 包含一个返回true
*/
private boolean haveCheck(List<String> targets, List<String> sources) {
if (targets == null || sources == null || targets.size() > sources.size()) {
return false;
}
for (String target : targets) {
if (sources.contains(target)) {
return true;
}
}
return false;
}
}
四、创建配置类,实现
WebMvcConfigurer
接口,重写addInterceptors
方法,添加拦截器。
/**
* @author xukun
* @date 2020/7/28
*/
@Configuration
public class StaticConfig implements WebMvcConfigurer {
/**
* 将自定义的拦截器交给Spring容器管理
*/
@Bean
public SecurityInterceptor getSecurityInterceptor() {
return new SecurityInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//添加自定义的拦截器
InterceptorRegistration addInterceptor = registry.addInterceptor(getSecurityInterceptor());
//拦截所有请求
addInterceptor.addPathPatterns("/**");
}
}
五、重启项目,进行测试