前言
问了下大模型,说是先进行参数校验,然后再执行切面逻辑;我用公司的框架,也是这个现象;但是用了一下SpringBoot,发现是相反的;
实践
接口
import com.haiwen.springbootsecuritysamples.aop.Auth;
import org.hibernate.validator.constraints.Length;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@Validated
@RestController
public class HelloController {
@Auth(role = "admin")
@GetMapping("/hello/{name}")
@Length(min = 1, max = 10, message = "invalid name")
public String sayHello(@PathVariable(name = "name") String name) {
return String.format("hello: %s", name);
}
}
注解
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Auth {
String role() default "dev";
}
切面
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Objects;
@Aspect
@Component
public class AuthAspect {
@Around("@annotation(Auth)")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Auth annotation = method.getAnnotation(Auth.class);
String role = "dev";
if (Objects.nonNull(annotation)) {
role = annotation.role();
}
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
String authorization = request.getHeader("Authorization");
if (!role.equals(authorization)) {
throw new RuntimeException("no authorization");
}
return joinPoint.proceed();
}
}
先执行了切面逻辑