package com.nju.edu.eval.aspect.auth; import com.auth0.jwt.exceptions.JWTVerificationException; import com.auth0.jwt.interfaces.Claim; import com.nju.edu.eval.data.entity.User; import com.nju.edu.eval.exception.MyServiceException; import com.nju.edu.eval.model.vo.user.PortalUserVO; import com.nju.edu.eval.service.UserService; import com.nju.edu.eval.service.convertor.UserConvertor; import com.nju.edu.eval.model.vo.user.UpdateUserVO; import com.nju.edu.eval.util.JwtUtil; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; /** * @author mars */ @Aspect @Configuration @Order(1) public class AuthAspect { private final UserService userService; @Autowired public AuthAspect(UserService userService) { this.userService = userService; } private User getUserByToken(String token) throws JWTVerificationException { try { Claim claim = JwtUtil.parseJwt(token); PortalUserVO userVO = claim.as(PortalUserVO.class); return new User(userVO.getId(), userVO.getRole(), userVO.getName(), userVO.getEmail(), userVO.getPhone(), new ArrayList<>(), null); } catch (MyServiceException e) { throw new MyServiceException(e.getCode(), e.getMessage()); } } @Before(value = "execution(public * com.nju.edu.eval.web.controller.*.*(..)) && @annotation(authorized)") public void authCheck(JoinPoint joinPoint, Authorized authorized) { HttpServletRequest httpServletRequest = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); String token = Optional.ofNullable(httpServletRequest.getHeader("Authorization")). orElseThrow(() -> new MyServiceException("A0223", "用户未获得第三方登录授权")); User user = getUserByToken(token); // 创建或者更新用户 if (userService.existsById(user.getId())) { userService.updateUser(new UpdateUserVO(user.getId(), user.getName(), user.getEmail())); } else { //TODO 这里没有对HR和TEACHER作区分 userService.createUser(UserConvertor.convertToVO(user)); } // 判断切面方法是否包含当前token对应的角色 if (!Arrays.stream(authorized.roles()).collect(Collectors.toList()).contains(user.getRole())) { throw new MyServiceException("A0301", "访问未授权"); } else { // 将token的对象赋值给切面方法的user参数 Object[] objects = joinPoint.getArgs(); for (Object o : objects) { if (o instanceof User) { System.out.println(user); BeanUtils.copyProperties(user, o); break; } } } } }