Meet is fate, pass by a praise ^


Source: https://github.com/yulc-coding/java-note/tree/master/aop

Train of thought

  • Custom permission annotations
  • Annotate the interface you want to validate and set specific permission values
  • Add permissions required by interfaces to the database permission table
  • When a user logs in, all permissions of the current user are obtained and put into Redis cache
  • Define AOP to set pointcuts to custom permissions
  • AOP to obtain the interface annotation permission value, and the data in Redis to verify whether the user has the permission, if not in Redis, then from the database to obtain the user permission list, and then verify

Pom files introduce AOP

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <! GroupId > <artifactId> Spring-boot-starter-AOP </artifactId> </artifactId> </dependency>Copy the code

Customize the annotation VisitPermission

@target (ElementType.METHOD) @Retention(retentionPolicy.runtime) public @interface VisitPermission {/** * Used to configure the permission value for a specific interface * Add the corresponding record to the database * when the user logs in, put the list of all permissions of the user into REDis * When the user accesses the interface, match the value of the corresponding interface with redis to see if the user has access permissions * When the user logs out, Clear redis' corresponding permission cache */ String value() default"";
}
Copy the code

Add the @visitPermission (value) annotation to the interface where permissions need to be set

@RestController
@RequestMapping("/permission"Public class PermissionController {/** * @visitPermission ("permission-test") * Only users with this permission can access, otherwise there is an illegal operation */ @visitPermission ("permission-test")
    @GetMapping("/test")
    public String test() {
        System.out.println("================== step 3: doing ==================");
        return "success"; }}Copy the code

Define permission AOP

Set the pointcut to @annotation(VisitPermission) Obtain the token in the request and verify whether the token is expired or valid Obtain the permission value in the annotation and verify whether the current user has access permission MongoDB Records access logs (IP addresses, parameters, interfaces, and time consuming).

@aspect @component public class PermissionAspect {/** * pointcuts * pointcuts under package path: execution(public * org.ylc.note.aop.controller.. * (..) ) : * org. Ylc. Note the aop) Controller package under any kind of any return value method of public * < p > * breakthrough point for the annotation: @annotation(VisitPermission) * Method where VisitPermission annotation exists */ @pointcut ("@annotation(org.ylc.note.aop.annotation.VisitPermission)")
    private void permission() {} /** * Before the target method is called */ @before ()"permission()")
    public void doBefore() {
        System.out.println("================== step 2: before =================="); } /** * the target method is called After */ @after ("permission()")
    public void doAfter() {
        System.out.println("================== step 4: after =================="); } /** * wrap Around the target method * validate the business data */ @around ("permission()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("================== step 1: around =================="); long startTime = System.currentTimeMillis(); /* * Get the token in the current HTTP request * parse the token: * 1, Token exists * 2, token format is correct * 3, token has expired (resolved information or exists in Redis) * */ ServletRequestAttributes Attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            throw new RuntimeException("Illegal request, invalid token"); } // Check the token business logic //... /* * Get the value of the annotation and verify the permission: * Redis does not have the corresponding permission * Redis does not have the corresponding permission from the database * Data in the air, throw exceptions, illegal requests, Have no jurisdiction * * / Method Method = (.) (MethodSignature proceedingJoinPoint getSignature ()). The getMethod (); VisitPermission visitPermission = method.getAnnotation(VisitPermission.class); String value = visitPermission.value(); // List<Object> permissions = redis.get(permission) // db.getPermission // permissions. Contains (value) // . System.out.println(value); / / perform specific methods Object result = proceedingJoinPoint. Proceed (); long endTime = System.currentTimeMillis(); /* / print the request url system.out.println ("URL : "+ request.getRequestURL().toString()); // Print Http method system.out.println ("HTTP Method : "+ request.getMethod()); // Prints the full path to call controller and the execution method system.out.println ("controller : "+ proceedingJoinPoint.getSignature().getDeclaringTypeName()); // Call system.out.println ("Method : "+ proceedingJoinPoint.getSignature().getName()); // Execution time System.out.println("cost-time : " + (endTime - startTime) + " ms");

        returnresult; }}Copy the code

Unit testing

package org.ylc.note.aop;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.ylc.note.aop.controller.PermissionController;

@SpringBootTest
class AopApplicationTests {

    @Autowired
    private PermissionController permissionController;

    private MockMvc mvc;

    @BeforeEach
    void setupMockMvc() {
        mvc = MockMvcBuilders.standaloneSetup(permissionController).build();
    }

    @Test
    void apiTest() throws Exception {
        MvcResult result = mvc.perform(MockMvcRequestBuilders.get("/permission/test")
                .accept(MediaType.APPLICATION_JSON)
                .header("token"."9527"))
                .andReturn();
        System.out.println("api test result : "+ result.getResponse().getContentAsString()); }}Copy the code

Please focus on