基于Spring拦截器自定义注解CheckAuth实现用户认证校验

基于Spring框架实现自定义登录验证CheckAuth注解,此注解主要用于类和方法上,实现接口调用时进行用户认证校验,注解代码如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.METHOD, ElementType.TYPE })
public @interface CheckAuth {
	
	String value() default "";

	String describe() default "";
}

自定义拦截器代码如下

import java.lang.annotation.Annotation;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ClassUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

public class AuthAnnotationInterceptor implements HandlerInterceptor {

	@Autowired
	AdminUtilsService adminUtils;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		CheckAuth CheckAuthAnnotation = findAnnotation(handler, CheckAuth.class);
		if (CheckAuthAnnotation != null && adminUtils != null) {
			boolean bLogin = adminUtils.isAuthenticated(); // 判断是否登录
			if (!bLogin) {
				response.reset();
				response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
				response.setCharacterEncoding("UTF-8");
				response.getWriter().write("Authentication required, Access denied.");
				response.flushBuffer();
				return false;
			}
			return true;
		}
		return HandlerInterceptor.super.preHandle(request, response, handler);
	}

	private <T extends Annotation> T findAnnotation(Object handler, Class<T> annotationClass) {

		if (handler instanceof HandlerMethod) {
			T annotation = null;
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			annotation = handlerMethod.getMethodAnnotation(annotationClass); // 此代码只能获取作用于方法上的注解
			if (annotation == null) {
                // 注解用于类上时,必须通过AnnotationUtils来获取类上的注解
				annotation = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), annotationClass);
			}
			return annotation;
		} else {
			return AnnotationUtils.findAnnotation(ClassUtils.getUserClass(handler), annotationClass);
		}

	}

}

本人使用的shiro权限框架,为了模块解耦,随意组合,避免注解模块依赖于shiro,特地定义了AdminUtilsService来实现解耦,使之整合到其他项目时,只要实现AdminUtilsService接口就可以。

其中adminUtils.isAuthenticated()方法代码如下所示:

public boolean isAuthenticated() {
    // 很多时候基于token或session里面的值来判断是否登录的,shiro是通过如下代码来判断的。
	return SecurityUtils.getSubject().isAuthenticated();
}

   特别要注意的,获取注解时,网上很多代码获取直接都只实现了如下代码

if (handler instanceof HandlerMethod) {
	CheckAuth annotation = null;
	HandlerMethod handlerMethod = (HandlerMethod) handler;
	annotation = handlerMethod.getMethodAnnotation(CheckAuth.class);


    省略。。。。
}

这样判断只能获取方法上面的注解

上面代码用户

public class DemoController {
   @CheckAuth
   public Result getList() {
      // 代码省略
   }
}

假如注解作用于类上,即@Target(value={ElementType.TYPE},获取注解就不能用handlerMethod.getMethodAnnotation(CheckAuth.class);来获取了,幸运的是Spring本身自带了一个获取的注解工具类AnnotationUtils.findAnnotation,可以获取类上的注解。通过AnnotationUtils.findAnnotation来查找注解后,我们就不需要每个接口方法都添加@CheckAuth注解,使用方法如下:

@CheckAuth
public class DemoController {
   
   public Result getList() {
      // 代码省略
   }
   
   public Result getUser() {
      // 代码省略
   }
}

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值