在Springboot通过注解简单实现权限控制
自定义一个注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserAuthorization {
}
复制代码
其中@Target注解解决这个自定义注解可以加载哪些成分上,比如方法、类、属性
- TYPE 类,接口(包括注释类型)或枚举声明
- FIELD 字段声明(包括枚举常量)
- METHOD 方法声明
- PARAMETER 形式参数声明
- CONSTRUCTOR 构造函数声明
- LOCAL_VARIABLE 局部变量声明
- ANNOTATION_TYPE 注释类型声明
- PACKAGE 包
- TYPE_PARAMETER 类型参数声明
- TYPE_USE 使用类型
其中Retention注解决定这个自定义注解的生命周期
- SOURCE 注解只在java源文件中存在,注释将被编译后丢弃
- CLASS 编译成.class文件后注解还在,被类加载器加载到内存中后就不存在了
- RUNTIME 注解的生命周期一直程序运行时都存在,可以以反射方式读取它们
配置一个拦截器
@Configuration
public class WebAppConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
/**
* 添加拦截器
*/
registry.addInterceptor(new AuthorizationInterceptor2())
.addPathPatterns("/api/**");
}
}
复制代码
拦截器的实现
public class AuthorizationInterceptor2 extends HandlerInterceptorAdapter {
/**
* Key的Request Key
*/
public static final String REQUEST_CURRENT_KEY = "REQUEST_CURRENT_KEY";
/**
* 存放鉴权信息的Header名称
*/
private String httpHeaderName = "sessionId";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/**
* 如果不是映射到方法直接通过
*/
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
String token = request.getHeader(httpHeaderName);
if (token != null && token.length() > 0) {
/**
* 根据token拿key,如果不为空则返回true
*/
String key = "";
if (key != null) {
request.setAttribute(REQUEST_CURRENT_KEY, key);
return true;
}
}
/**
* 如果验证token失败,并且方法或类注明了Authorization,返回错误
*/
if (method.getAnnotation(Authorization.class) != null || handlerMethod.getBeanType().getAnnotation(Authorization.class) != null) {
throw new ApiException(ApiConstants.SESSIONIDEXCEPTION, "权限异常");
}
request.setAttribute(REQUEST_CURRENT_KEY, null);
return true;
}
}
复制代码
这样就可以在类上或方法上加UserAuthorization 实现权限控制