拦截器进行权限判断

定义一个拦截器

/**
 *版权所有:爱wifi无线运营中心
 * 创建日期:2018年10月16日上午11:10:12
 *文件名称:AccessTokenVerifyInterceptor.java
 *创建作者:付少林
 *
 */
package com.awifi.athena.app.smart.elevator.common.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.awifi.athena.app.smart.elevator.common.business.usermanage.permission.entity.UserPermission;
import com.awifi.athena.app.smart.elevator.common.business.usermanage.user.dto.UserInfoDto;
import com.awifi.athena.app.smart.elevator.common.business.usermanage.user.dto.UserInfoPermissionDto;
import com.awifi.athena.app.smart.elevator.common.constants.Constants;
import com.awifi.athena.app.smart.elevator.common.exception.BizException;
import com.awifi.athena.app.smart.elevator.common.exception.ValidException;
import com.awifi.athena.app.smart.elevator.common.utils.KeyUtil;
import com.awifi.athena.app.smart.elevator.common.utils.MessageUtil;
import com.awifi.athena.app.smart.elevator.common.utils.RequestMappingUrlUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import java.util.List;

/**
 * 验证token有效性
 */
@Component
public class AccessTokenVerifyInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{
        boolean flag = false;
        String accessToken = request.getParameter("access_token");
        if(StringUtils.isNoneBlank(accessToken)) {
        	UserInfoPermissionDto usrDto = KeyUtil.getAdminUserByAccessToken(accessToken);
            if(usrDto!=null){
                List<UserPermission> list = usrDto.getUserPermissions();
                if(list==null||list.size()==0){
                    throw new BizException("E1000003", MessageUtil.getMessage("E1000003"));
                }
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                //拿到请求类的类型
                String beanType = handlerMethod.getBeanType().getName();
                //获得请求类的字节码文件
                Class clazz = Class.forName(beanType);
                //http请求的url,防止一些url占位符的问题,对url进行了处理
                String url = RequestMappingUrlUtil.getRequestMappingUrl(clazz,beanType+"."+handlerMethod.getMethod().getName());
                String method = request.getMethod();
                for (UserPermission userPermission:list) {//对url进行处理使url前后都有/方便进行比较,容错性比较好
                    if(userPermission.getUrl()!=null){
                        if(!userPermission.getUrl().startsWith("/")){
                            userPermission.setUrl("/"+userPermission.getUrl());
                        }
                        if(!userPermission.getUrl().endsWith("/")){
                            userPermission.setUrl(userPermission.getUrl()+"/");
                        }
                    }
                    if(userPermission.getMethod()!=null){
                        userPermission.setMethod(StringUtils.upperCase(userPermission.getMethod()));
                    }
                }
                if(!url.startsWith("/")){
                    url = "/"+url;
                }
                if(!url.endsWith("/")){
                    url = url+"/";
                }
                if(!list.contains(new UserPermission(url,method))){
                    throw new BizException("E1000003", MessageUtil.getMessage("E1000003"));
                }
                flag = true;
                //塞到request中去,供controller里面调用
                request.setAttribute(Constants.SESSION_NAME_USER,usrDto);
            }
        }

        if(!flag){
        	throw new ValidException("E1000002", "请重新登录");
        }
        return flag;
    }

}
package com.awifi.athena.app.smart.elevator.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 版权所有: 爱WiFi无线运营中心
 * 创建日期:2018/12/5
 * 创建作者:付少林
 * 文件名称:RequestMappingUrlUtil.java
 * 版本:  v1.0
 * 修改记录:
 */
public class RequestMappingUrlUtil {
    public static String getRequestMappingUrl(Class controller, String methodName) {
        //得到方法
        Method[] methods = controller.getDeclaredMethods();
        String[] value = new String[1];
        Annotation classAnnotation = AnnotationHelper.getInstance().getClassAnnotation(controller, RequestMapping.class);
        String classUrl = "";
        try {
            List<RequestUrlInfo> urlList = getRequestUrlInfos(classAnnotation);
            if(urlList!=null&&urlList.size()>0){
                classUrl = urlList.get(0).getValue();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        for (Method method : methods) {
            String className = controller.getName() + "." + method.getName();
            if (!StringUtils.equals(className, methodName)) {
                continue;
            }
            //得到requestMapping注释
            RequestMapping annotation = method.getAnnotation(RequestMapping.class);
            GetMapping getAnnotation = method.getAnnotation(GetMapping.class);
            PostMapping postAnnotation = method.getAnnotation(PostMapping.class);
            DeleteMapping deleteAnnotation = method.getAnnotation(DeleteMapping.class);
            PutMapping putAnnotation = method.getAnnotation(PutMapping.class);
            try {
                if (annotation != null) {
                    value[0] = annotation.value()[0];
                }
                if (getAnnotation != null) {
                    value[0] = getAnnotation.value()[0];
                }
                if (postAnnotation != null) {
                    value[0] = postAnnotation.value()[0];
                }
                if (deleteAnnotation != null) {
                    value[0] = deleteAnnotation.value()[0];
                }
                if (putAnnotation != null) {
                    value[0] = putAnnotation.value()[0];
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            break;
        }
        return classUrl+value[0];
    }

    /**
     * 将RequestMapping注解信息,组装成RequestUrlInfo类中。此类方法共有三种重载方式,分别为Annotation、提供basePath、提供classAnnotation注解三种方式。
     * @param annotation  参数
     * @return  注解信息
     */
    public  static List<RequestUrlInfo> getRequestUrlInfos(Annotation annotation) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        List<RequestUrlInfo> infos = new ArrayList<>();

        if(annotation == null) {
            return infos;
        }

        String name = (String) AnnotationHelper.getInstance().getAnnotationInfo(annotation, "name");
        List<String> requestUrls = Arrays.asList((String[]) AnnotationHelper.getInstance().getAnnotationInfo(annotation, "value"));
        List<RequestMethod> requestMethods = Arrays.asList((RequestMethod[]) AnnotationHelper.getInstance().getAnnotationInfo(annotation, "method"));

        if(requestMethods.isEmpty()) {
            for(String url : requestUrls) {
                RequestUrlInfo info = new RequestUrlInfo(name);

                info.setValue(url);
                info.setRequestMethod(null);

                infos.add(info);
            }
        } else {
            for(String url : requestUrls) {
                for(RequestMethod method : requestMethods) {
                    RequestUrlInfo info = new RequestUrlInfo(name);

                    info.setValue(url);
                    info.setRequestMethod(method);

                    infos.add(info);
                }
            }
        }

        return infos;
    }
}

 

### 使用拦截器实现登录权限验证 在Web应用程序开发中,确保只有经过身份验证并具有适当角色的用户才能访问特定资源至关重要。通过使用Spring MVC中的拦截器可以有效地实现在控制器层面上的方法调用前进行安全检查。 #### 实现思路 为了完成这一目标,需要创建自定义拦截器来处理以下逻辑: - 验证当前会话是否存在有效用户信息; - 解析被调用方法上指定的安全注解(如`@RequiresRoles`),从中读取所需的角色集合; - 对比当前用户的授权情况与预期匹配,决定是否允许继续执行业务逻辑还是返回未授权错误响应[^1]。 下面是一个简单的Java代码片段展示如何构建这样的功能: ```java import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class AuthInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 只针对HandlerMethod类型的处理器生效 if (handler instanceof HandlerMethod){ HandlerMethod method = (HandlerMethod) handler; RequiresRoles rolesAnnotation = method.getMethodAnnotation(RequiresRoles.class); String[] requiredRoleList = null; if(null != rolesAnnotation && !rolesAnnotation.value().isEmpty()){ requiredRoleList = rolesAnnotation.value(); // 假设有一个工具类UserService用于获取当前登录用户及其拥有的角色列表 List<String> currentUserRoles = UserService.getCurrentUserRoles(); // 判断是否有交集 Set<String> intersectionSet = new HashSet<>(Arrays.asList(requiredRoleList)); intersectionSet.retainAll(currentUserRoles); if(intersectionSet.isEmpty()){// 如果没有任何共同项,则拒绝访问 throw new AuthorizationException("Insufficient permissions"); } }else{ // 当没有设置任何角色限制时,默认放行 return true; } } return super.preHandle(request,response,handler); } } ``` 此段程序展示了如何利用继承自`HandlerInterceptorAdapter`的方式编写一个名为`AuthInterceptor`的拦截器实例。该拦截器会在每次HTTP请求到达对应的Controller之前触发其内部定义好的预处理函数——即重写的`preHandle()`方法内所描述的行为流程[^2]。 对于实际项目而言,还需要配置好这个新建立起来的拦截器以便它能够正常工作于整个应用之中,并且可能涉及到更多细节方面的调整优化,比如更复杂的认证机制集成或是更加灵活多变的角色管理策略等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值