欢迎访问github
近期因为业务需求,用户类型进行了细致的区分,各个接口的权限都要进行判断,一开始在每个接口中写判断方法,后来实在太多,所以采用注解的形式实现粗粒度的鉴权。
自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Authenticate {
/**
* 权限列表,以“,”分割的权限编号
*
* @return
*/
String permissions();
}
就一个属性,存储权限编号列表。
注解实现
@Aspect
@Component
public class AuthenticateHandle {
private static final Logger logger = LoggerFactory.getLogger(WebActionAspecter.class);
@Around("execution(public * * (..) ) && @annotation(com.jincloud.crm.authenticate.Authenticate)")
public Result access(ProceedingJoinPoint point) {
AuthorizedUser info = SecurityUtil.getCurrentUser();
MethodSignature methodSignature = MethodSignature.class.cast(point.getSignature());
Authenticate auth = fetchAuth(methodSignature);
if (!handleAuth(auth, info)) {
logger.error("您没有权限进行该操作,方法名:{},用户ID:{}", methodSignature, info.getId());
return Result.fail("您没有权限进行该操作");
}
Result result = null;
try {
result = (Result) point.proceed();
} catch (Throwable e) {
logger.error("", e);
return Result.fail(e.getMessage());
}
return result;
}
private Authenticate fetchAuth(MethodSignature methodSignature) {
return methodSignature.getMethod().getAnnotation(Authenticate.class);
}
private Boolean handleAuth(Authenticate auth, AuthorizedUser info) {
String[] permissionsStr = auth.permissions().split(",");
List<String> permissions = Lists.newArrayList(permissionsStr);
for (String permission : info.getStringPermissions()) {
if (permissions.contains(permission)) {
return true;
}
}
return false;
}
}
就是把当前登录用户的权限取出,去和注解的permissions属性允许的权限比较,有就通过,没有就返回错误,
handleAuth是处理方法,可以根据业务需求自己随意定义。
使用
@RequestMapping(value = "/siteCollector/{id}/delete", method = { RequestMethod.POST })
@Authenticate(permissions = "0,2")
public Result delete(@PathVariable Long id) {
siteCollectorService.delete(id);
return Result.success();
}
这样一个简单的粗粒度鉴权就实现了。