1. 程式人生 > 其它 >使用自定義註解校驗使用者授權和獲取授權資訊

使用自定義註解校驗使用者授權和獲取授權資訊

/********************** 自定義 授權攔截註解***********************************/

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthToken {
boolean required() default true;
}

/********************** 自定義 授權資訊註解***********************************/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ApiIgnore
public @interface AuthUser {
}

/****************************** 使用者授權登入攔截 *************************************/
@Component
@Slf4j
public class AuthUserInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws AuthorizationException {
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
// 如果不是對映到方法檢視controller層註解
if (method.isAnnotationPresent(AuthToken.class) || handlerMethod.getBeanType().isAnnotationPresent(AuthToken.class)) {
//登入驗證
AuthToken authToken = method.isAnnotationPresent(AuthToken.class) ?
method.getAnnotation(AuthToken.class) : handlerMethod.getBeanType().getAnnotation(AuthToken.class);
if (authToken.required()) {
// 從 http 請求頭中取出 token
String token = request.getHeader(IAuthConst.KEY_AUTHORIZATION);
// token認證
if (null == token) {
throw new AuthorizationException(IAuthConst.KEY_AUTHORIZATION + "不能為空");
}
// 在此根據token獲取到使用者授權資訊,然後寫入到request
request.setAttribute(IAuthConst.KEY_USER_ID, 1);
request.setAttribute(IAuthConst.KEY_USER_NAME, "admin");
}
}
return true;
}
}

/***********************************使用者資訊欄位 Resolver*****************************************/
@Component
public class AuthUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
/**
* 此方法攔截加了註解的引數 方法
*
* @param parameter
* @return
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
if (parameter.hasParameterAnnotation(AuthUser.class)) {
return true;
}
return false;
}

/**
* 對加了自定義註解的方法進行業務操做
*
* @return
* @throws Exception
*/
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) {
if (parameter.hasParameterAnnotation(AuthUser.class)) {
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
Object userIdObj = servletRequest.getAttribute(IAuthConst.KEY_USER_ID);
Object userNameObj = servletRequest.getAttribute(IAuthConst.KEY_USER_NAME);
if (userIdObj != null && userNameObj != null && userIdObj instanceof Integer) {
return new UserBase(Integer.parseInt(userIdObj.toString())
, userNameObj.toString());
}
}
return null;
}
}

/*************************** 新增攔截器到spring*****************************************/
@Configuration
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
//註冊到spring容器中
@Resource
private AuthUserMethodArgumentResolver handlerParameterResolver;

//新增對方法的攔截
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(handlerParameterResolver);
super.addArgumentResolvers(argumentResolvers);
}

/**
* 新增對使用者授權的攔截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 可新增多個
registry.addInterceptor(new AuthUserInterceptor()).addPathPatterns("/**");
}
}