主要思想是基于环绕aop得到 controller方法上的注解权限。再与前面拦截器得到的用户权限进行比较。
拦截器与其配置文件:
参考文献:
1.切面匹配表达式。
https://www.cnblogs.com/songshuiyang/p/7857515.html
2.springboot aop。
https://www.cnblogs.com/huanzi-qch/p/9916478.html
3.获取注解的属性值
https://blog.csdn.net/HaHa_Sir/article/details/81331437
package com.example.demo928.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {//WebMvcConfigurationSuppor自动配置失效
@Autowired
private AccountInteceptor accountInteceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注意排除swagger-ui
registry.addInterceptor(accountInteceptor)
.addPathPatterns(
"/**"
)
.excludePathPatterns(
"/**/login/**",
"/**/register/**",
"/**/*.html",
"/**/*.js",
"/**/*.css",
"/**/*.jpg",
"/**/*.mp3",
"/swagger-resources/**",
"/webjars/**",
"/v2/**",
"/swagger-ui.html/**"
);
}
//注意排除swagger-ui
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
package com.example.demo928.config;
import ch.qos.logback.core.net.SyslogOutputStream;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
@Component
public class AccountInteceptor implements HandlerInterceptor {
@Autowired
HttpServletResponse response;
@Autowired
HttpServletRequest request;
private ObjectMapper objectMapper=new ObjectMapper();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HashSet<String> set=new HashSet<>();
set.add("abc");
set.add("run");
set.add("sleep");
// set.add("sleep");
request.setAttribute("permission",set);
return true;
}
private void returnJson(String json){
PrintWriter writer = null;
response.setCharacterEncoding("UTF-8");
response.setContentType("text/json; charset=utf-8");
try {
writer = response.getWriter();
writer.print(json);
} catch (IOException e) {
System.out.println("回写错误!");
} finally {
if (writer != null) {
writer.close();
}
}
}
}
aop切面:
package com.example.demo928.aop;
import com.example.demo928.annotation.Permission;
import com.example.demo928.config.BaseResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
/**
* Aspect 切面
* 日志切面
*/
@Aspect
@Component
public class LogAspect {
/**
* slf4j日志
*/
private final static Logger logger = LoggerFactory.getLogger(LogAspect.class);
/**
* Pointcut 切入点
* 匹配controller包下面的所有方法
*/
@Pointcut("execution( * *..controller..*(..))")
//@Pointcut("execution( * com..*.controller..*(..))")
public void webLog(){}
@Autowired
HttpServletRequest request;
@Autowired
HttpServletResponse response;
ObjectMapper objectMapper=new ObjectMapper();
/**
* 环绕通知
*/
@Around(value = "webLog()")
public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
Object o=null;
//ProceedingJoinPoint封装类信息
Signature signature = joinPoint.getSignature();
String methodName = signature.getName();
Class clazz = signature.getDeclaringType();
Method method = clazz.getDeclaredMethod(methodName);
//获取注解上的值
Permission permission = method.getAnnotation(Permission.class);
String[] value = permission.value();
o = joinPoint.proceed();
//权限检查
HashSet<String> set=(HashSet<String>)request.getAttribute("permission");//拦截器取得的权限
for(String v:value){
System.out.println("权限:"+v);
if(!set.contains(v)){
System.out.println("权限不够!!");
returnJson(objectMapper.writeValueAsString(new BaseResponse(400,"权限不够!!")));
return null;
}
}
return o;
}
private void returnJson(String json){
PrintWriter writer = null;
response.setCharacterEncoding("UTF-8");
response.setContentType("text/json; charset=utf-8");
try {
writer = response.getWriter();
writer.print(json);
} catch (IOException e) {
System.out.println("回写错误!");
} finally {
if (writer != null) {
writer.close();
}
}
}
}
自定义权限注解:
package com.example.demo928.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Permission {
String[] value();
}
controller:
package com.example.demo928.controller;
import com.example.demo928.annotation.Permission;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@GetMapping("/f1")
@Permission({"run","sleep"})
String f1(){
System.out.println("已执行controller!!");
return "f1!!!!!!!";
}
}