spring boot 利用註解實現許可權驗證

蘭茗翔發表於2019-01-19

這裡使用 aop 來實現許可權驗證

引入依賴


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

定義註解

package com.lmxdawn.api.admin.annotation;

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

/**
 * 後臺登入授權/許可權驗證的註解
 */
//此註解只能修飾方法
@Target(ElementType.METHOD)
//當前註解如何去保持
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthRuleAnnotation {
    String value();
}

攔截實現登入和許可權驗證

package com.lmxdawn.api.admin.aspect;

import com.lmxdawn.api.admin.annotation.AuthRuleAnnotation;
import com.lmxdawn.api.admin.enums.ResultEnum;
import com.lmxdawn.api.admin.exception.JsonException;
import com.lmxdawn.api.admin.service.auth.AuthLoginService;
import com.lmxdawn.api.common.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
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.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.List;

/**
 * 登入驗證 AOP
 */
@Aspect
@Component
@Slf4j
public class AuthorizeAspect {

    @Resource
    private AuthLoginService authLoginService;

    @Pointcut("@annotation(com.lmxdawn.api.admin.annotation.AuthRuleAnnotation)")
    public void adminLoginVerify() {
    }

    /**
     * 登入驗證
     *
     * @param joinPoint
     */
    @Before("adminLoginVerify()")
    public void doAdminAuthVerify(JoinPoint joinPoint) {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            throw new JsonException(ResultEnum.NOT_NETWORK);
        }
        HttpServletRequest request = attributes.getRequest();

        String id = request.getHeader("X-Adminid");

        Long adminId = Long.valueOf(id);

        String token = request.getHeader("X-Token");
        if (token == null) {
            throw new JsonException(ResultEnum.LOGIN_VERIFY_FALL);
        }

        // 驗證 token
        Claims claims = JwtUtils.parse(token);
        if (claims == null) {
            throw new JsonException(ResultEnum.LOGIN_VERIFY_FALL);
        }
        Long jwtAdminId = Long.valueOf(claims.get("admin_id").toString());
        if (adminId.compareTo(jwtAdminId) != 0) {
            throw new JsonException(ResultEnum.LOGIN_VERIFY_FALL);
        }

        // 判斷是否進行許可權驗證
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //從切面中獲取當前方法
        Method method = signature.getMethod();
        //得到了方,提取出他的註解
        AuthRuleAnnotation action = method.getAnnotation(AuthRuleAnnotation.class);
        // 進行許可權驗證
        authRuleVerify(action.value(), adminId);
    }

    /**
     * 許可權驗證
     *
     * @param authRule
     */
    private void authRuleVerify(String authRule, Long adminId) {

        if (authRule != null && authRule.length() > 0) {

            List<String> authRules = authLoginService.listRuleByAdminId(adminId);
            // admin 為最高許可權
            for (String item : authRules) {
                if (item.equals("admin") || item.equals(authRule)) {
                    return;
                }
            }
            throw new JsonException(ResultEnum.AUTH_FAILED);
        }

    }

}

Controller 中使用

使用 AuthRuleAnnotation 註解, value 值就是在資料庫裡面定義的 許可權規則名稱

/**
 * 獲取管理員列表
 */
@AuthRuleAnnotation("admin/auth/admin/index")
@GetMapping("/admin/auth/admin/index")
public ResultVO index(@Valid AuthAdminQueryForm authAdminQueryForm,
                      BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        return ResultVOUtils.error(ResultEnum.PARAM_VERIFY_FALL, bindingResult.getFieldError().getDefaultMessage());
    }

    if (authAdminQueryForm.getRoleId() != null) {
        List<AuthRoleAdmin> authRoleAdmins = authRoleAdminService.listByRoleId(authAdminQueryForm.getRoleId());
        List<Long> ids = new ArrayList<>();
        if (authRoleAdmins != null && !authRoleAdmins.isEmpty()) {
            ids = authRoleAdmins.stream().map(AuthRoleAdmin::getAdminId).collect(Collectors.toList());
        }
        authAdminQueryForm.setIds(ids);
    }
    List<AuthAdmin> authAdminList = authAdminService.listAdminPage(authAdminQueryForm);

    // 查詢所有的許可權
    List<Long> adminIds = authAdminList.stream().map(AuthAdmin::getId).collect(Collectors.toList());
    List<AuthRoleAdmin> authRoleAdminList = authRoleAdminService.listByAdminIdIn(adminIds);

    // 檢視列表
    List<AuthAdminVo> authAdminVoList = authAdminList.stream().map(item -> {
        AuthAdminVo authAdminVo = new AuthAdminVo();
        BeanUtils.copyProperties(item, authAdminVo);
        List<Long> roles = authRoleAdminList.stream()
                .filter(authRoleAdmin -> authAdminVo.getId().equals(authRoleAdmin.getAdminId()))
                .map(AuthRoleAdmin::getRoleId)
                .collect(Collectors.toList());
        authAdminVo.setRoles(roles);
        return authAdminVo;
    }).collect(Collectors.toList());

    PageInfo<AuthAdmin> authAdminPageInfo = new PageInfo<>(authAdminList);
    PageSimpleVO<AuthAdminVo> authAdminPageSimpleVO = new PageSimpleVO<>();
    authAdminPageSimpleVO.setTotal(authAdminPageInfo.getTotal());
    authAdminPageSimpleVO.setList(authAdminVoList);

    return ResultVOUtils.success(authAdminPageSimpleVO);

}

相關地址

GitHub 地址: https://github.com/lmxdawn/vu…

相關文章