SpringAop實現許可權校驗與日誌列印
使用springboot+aop實現使用者的許可權校驗與日誌的列印
Base切面
/**
* @Description 基礎切面類
* @author xpWang
* @date 2020/1/6 16:13
*/
public class BaseAspect {
protected Method method;
protected Class clazz;
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) || "
+ "@annotation(org.springframework.web.bind.annotation.GetMapping) || "
+ "@annotation(org.springframework.web.bind.annotation.PostMapping)||"
+ "@annotation(org.springframework.stereotype.Controller)||"
+ "@annotation(org.springframework.web.bind.annotation.RestController)")
void requestMapping() {
}
protected void init(JoinPoint joinPoint) throws NoSuchMethodException {
clazz = joinPoint.getTarget().getClass();
Signature signature = joinPoint.getSignature();
MethodSignature msg = (MethodSignature) signature;
method = clazz.getMethod(msg.getName(), msg.getParameterTypes());
}
}
許可權校驗父類
/**
* @Description 使用者資訊相關切面
* @author xpWang
* @date 2020/1/6 16:13
*/
@Slf4j
public class BaseTokenAspect extends BaseAspect{
@Autowired
private IAuthinfoService authinfoService;
protected String token;
protected AuthInfo authInfo;
@Override
protected void init(JoinPoint joinPoint) throws NoSuchMethodException {
super.init(joinPoint);
token = RequestUtil.getToken();
if (StringUtils.isNotEmpty(token)) {
try {
authInfo = authinfoService.getAuthInfo(token);
} catch (Exception e) {
log.warn("authinfoService getAuthInfo exceprtion :"+e);
}
}
}
protected ErrorCode checkToken() {
log.info("check auth.");
if (StringUtils.isEmpty(token)) {
return ErrorCode.TOKEN_NOTOKEN;
}
return authinfoService.checkToken(token);
}
protected Object[] getAuthinfoArgs(JoinPoint joinPoint) throws Exception {
Object[] args = joinPoint.getArgs();
int index=checkParameterHasAuth(method);
if (index!=-1){
log.info("set authinfo");
if (authInfo!=null){
args[index]=authInfo;
}else{
log.warn("there is no cache");
}
}
return args;
}
/**
* @Description 檢查方法引數是否有cn.com.taiji.system.domain.rbac.AuthInfo
* @return int 返回引數AuthInfo所在Index,如果沒有返回-1
* @author xpWang
* @date 2020/1/6 11:43
*/
private int checkParameterHasAuth(Method method){
Class<?>[] parameterTypes = method.getParameterTypes();
for(int i=0;i<parameterTypes.length;i++){
if (parameterTypes[i].isAssignableFrom(AuthInfo.class)){
return i;
}
}
return -1;
}
}
token驗證切面
/**
* @Description 驗證token注入auth
* @author xpWang
* @date 2020/1/6 16:14
*/
@Aspect
@Component
@Slf4j
@Order(1)
public class TokenMethodAspect extends BaseTokenAspect{
@Around("requestMapping()&&@annotation(cn.com.taiji.framework.annotation.TokenMethod)")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
try {
this.init(joinPoint);
Annotation[] annotations = method.getAnnotationsByType(TokenMethod.class);
if (ObjectUtils.isEmpty(annotations)) {
return joinPoint.proceed();
}
log.info("ClassName:\t" + clazz.getSimpleName()+"\tMethodName:\t" + method.getName());
ErrorCode errorCode=checkToken();
if (ErrorCode.TOKEN_CHECK_SUCCESS!=errorCode){
log.error(errorCode.toJsonString());
return new ObjectResponse(errorCode);
}
Object[] args=this.getAuthinfoArgs(joinPoint);
return joinPoint.proceed(args);
} catch (NoSuchMethodException e) {
return new ObjectResponse().error("token aspect init exception.");
} catch (Exception ex){
return new ObjectResponse().error("token aspect doarround exception",ex);
}
}
}
許可權校驗切面
/**
* @Description 驗證token,permission注入auth
* @author xpWang
* @date 2020/1/6 16:14
*/
@Aspect
@Component
@Slf4j
@Order(2)
public class TokenPermissionMethodAspect extends BaseTokenAspect {
/**
* @Description 驗證token, 注入Auth
* @author xpWang
* @date 2020/1/6 14:53
*/
@Around("requestMapping()&&@annotation(cn.com.taiji.framework.annotation.TokenPermissionMethod)")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
if (!RequestUtil.isNeedPermission()){
log.debug("checkAuthPermission isNeedPermission is false.");
return joinPoint.proceed();
}
try {
this.init(joinPoint);
log.info("ClassName:\t" + clazz.getSimpleName() + "\tMethodName:\t" + method.getName());
ErrorCode errorCode = checkToken();
if (ErrorCode.TOKEN_CHECK_SUCCESS != errorCode) {
log.error(errorCode.toJsonString());
return new ObjectResponse(errorCode);
}
ErrorCode perErrorCode = checkAuthPermission();
if (ErrorCode.SUCCESS!=perErrorCode){
log.error(perErrorCode.toJsonString());
return new ObjectResponse(perErrorCode);
}
log.info("permission verify success.");
TokenPermissionMethod annotation = method.getAnnotation(TokenPermissionMethod.class);
if (annotation.onlyCheck()){
return new ObjectResponse(ErrorCode.PERMISSION_CHECK_SUCCESS);
}
Object[] args = this.getAuthinfoArgs(joinPoint);
return joinPoint.proceed(args);
} catch (NoSuchMethodException e) {
return new ObjectResponse().error("token aspect init exception.");
} catch (Exception ex) {
return new ObjectResponse().error("TokenPermissionMethodAspect aspect doAround exception", ex);
}
}
/**
* @Description 檢查使用者許可權
* @author xpWang
* @date 2020/1/6 15:49
*/
private ErrorCode checkAuthPermission(){
if (authInfo == null) {
return ErrorCode.PERMISSION_NO_CACHE;
}
Integer perId = RequestUtil.getPerId();
Integer nodeId = RequestUtil.getNodeId();
log.debug("checkAuthPermission perId:\t"+perId+"\tnodeId:\t"+nodeId);
//check permission
if (perId != null &&
(authInfo.getPermissions() == null || !ArrayUtils.contains(authInfo.getPermissions(), perId))) {
return ErrorCode.PERMISSION_FAILED;
}
if (nodeId != null &&
(authInfo.getNodes() == null || !ArrayUtils.contains(authInfo.getNodes(), nodeId))) {
return ErrorCode.PERMISSION_FAILED;
}
return ErrorCode.SUCCESS;
}
}
controller日誌記錄
這裡的方法引數列印有問題,需要修改
@Aspect
@Component
@Slf4j
@Order(1)
public class ControllerLogAspect extends BaseAspect{
@Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) || "
+ "@annotation(org.springframework.web.bind.annotation.GetMapping) || "
+ "@annotation(org.springframework.web.bind.annotation.PostMapping)")
void requestLog() {
}
@Around("requestLog()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
long begin=System.currentTimeMillis();
init(joinPoint);
log.debug("BEGIN:\tClassName:\t" + clazz.getSimpleName()+"\tMethodName:\t" + method.getName()+"\targs:\t"+JSON.toJSONString(joinPoint.getArgs(), SerializerFeature.WriteMapNullValue));
//log.debug("BEGIN:\tClassName:\t" + clazz.getSimpleName()+"\tMethodName:\t" + method.getName()+"\targs:\t");
Object result=joinPoint.proceed();
log.debug("END:\tClassName:\t" + clazz.getSimpleName()+"\tMethodName:\t" + method.getName()+"\tCost:"+(System.currentTimeMillis()-begin)+"ms\tResult"+JSON.toJSONString(result));
return result;
}
}
annotation
/**
* @Description 需要進行Token以及許可權驗證的Controller註解
* @author xpWang
* @date 2020/1/6 11:27
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TokenPermissionMethod {
boolean onlyCheck() default false;
}
/**
* @Description 需要進行Token驗證的Controller註解
* @author xpWang
* @date 2020/1/6 11:27
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TokenMethod {
}
controller使用
/**
* @Description 使用者登入資訊相關服務
* @author xpWang
* @date 2019/12/31 10:23
*/
@RestController
@RequestMapping("/authinfo")
@Api(tags = "賬戶許可權管理系統-使用者認證", value = "authinfo")
public class AuthInfoController extends BaseController {
@Autowired
private IAuthinfoService authinfoService;
@PostMapping("/login")
@ApiOperation(notes = "登入介面", value = "login")
public AjaxResponse login(@RequestBody UserDO user) {
ObjectResponse response=new ObjectResponse();
AuthInfo auth = null;
try {
auth = authinfoService.login(user);
if (auth == null) {
return response.error("Incorrect user name or password");
}
return response.success("login success", auth);
} catch (Exception e) {
return response.error("login exception : " , e);
}
}
/**
* @Description AOP判斷了
* @author xpWang
* @date 2020/1/6 16:14
*/
@PostMapping("/checkAuth")
@ApiOperation(notes = "登入資訊許可權校驗", value = "checkAuth")
@TokenPermissionMethod(onlyCheck = true)
public AjaxResponse checkAuth() {
return new ObjectResponse(ErrorCode.PERMISSION_CHECK_SUCCESS);
}
/**
* 根據TOKEN獲取賬號資訊
*/
@PostMapping("/getAuthInfo")
@ApiOperation(notes = "賬號分頁查詢", value = "getAuthInfo")
@TokenMethod
public AjaxResponse getAuthInfo(AuthInfo authInfo) {
ObjectResponse response=new ObjectResponse();
try {
if (authInfo != null) {
return response.success("success.", authInfo);
} else {
return response.error("there is no authinfo in cache.");
}
} catch (Exception e) {
e.printStackTrace();
return response.error("getAuthInfo exception:\t",e);
}
}
public AuthInfoController(){
System.out.println("init AuthInfoController.");
}
}
相關文章
- *IT SpringAOP:足跡第十八步瞭解SpringAOP(實現許可權認證、日誌)Spring
- 分享!! 如何自定義許可權校驗的註解並用AOP攔截實現許可權校驗
- SpringSecurity:hasAuthority與自定義許可權校驗SpringGse
- 使用Servlet Filter實現系統登入許可權校驗ServletFilter
- 服務閘道器 Zuul 與 Redis 結合實現 Token 許可權校驗ZuulRedis
- drf 許可權校驗設定與原始碼分析原始碼
- 許可權控制及AOP日誌
- 關於 Laravel 日誌許可權Laravel
- Laravel Daily 日誌許可權問題LaravelAI
- SpringSecurity許可權管理系統實戰—二、日誌、介面文件等實現SpringGse
- Laravel 框架的日誌許可權問題Laravel框架
- Laravel 日誌檔案許可權問題Laravel
- Laravel 日誌有時候有許可權有時候沒有許可權?Laravel
- 如何用 Vue 實現前端許可權控制(路由許可權 + 檢視許可權 + 請求許可權)Vue前端路由
- artisan日誌 root 許可權解決辦法
- 記一次 Laravel日誌許可權許可權問題(定時器導致)Laravel定時器
- Laravel實現許可權控制Laravel
- ThinkPHP6 寫入日誌許可權報錯PHP
- Spring 使用Aop 做切面日誌,和許可權。Spring
- oracle實驗記錄 (許可權,role)Oracle
- spring boot 利用註解實現許可權驗證Spring Boot
- 角色許可權(Role)和系統許可權(System)的幾個澄清實驗
- 淺談許可權管理的設計與實現
- Android多程式之Binder的意外死亡及許可權校驗Android
- mysql之許可權驗證MySql
- Vue許可權路由實現總結Vue路由
- 基於RBAC實現許可權管理
- 從0實現RBAC許可權模型模型
- spring aop實現許可權管理Spring
- Django許可權機制的實現Django
- Spring Security實現統一登入與許可權控制Spring
- 使用動態路由實現許可權管理路由
- vue許可權路由實現方式總結Vue路由
- Fake許可權驗證小例子
- Oracle的物件許可權、角色許可權、系統許可權Oracle物件
- 如何優雅的使用切面和註解實現許可權驗證
- Django(63)drf許可權原始碼分析與自定義許可權Django原始碼
- 許可權之選單許可權