SpringMVC 拦截器实现权限统一校验(重点)

Spring MVC拦截器流程图:

第一步:在springmvc.xml里面配置拦截器

    <mvc:interceptors>
        <!-- 定义在这里的,所有的都会拦截-->
        <mvc:interceptor>
            <!--manage/a.do  /manage/*-->
            <!--manage/b.do  /manage/*-->
            <!--manage/product/save.do /manage/**-->
            <!--manage/order/detail.do /manage/**-->
            <mvc:mapping path="/manage/**"/>
            <!--<mvc:exclude-mapping path="/manage/user/login.do"/>-->
            <bean class="com.mmall.controller.common.interceptor.AuthorityInterceptor" />
        </mvc:interceptor>

    </mvc:interceptors>

第二步:在controller包下的common包里面书写AuthorityInterceptor类并实现HandlerInterceptor类

package com.mmall.controller.common.interceptor;

import com.google.common.collect.Maps;
import com.mmall.common.Const;
import com.mmall.common.ServerResponse;
import com.mmall.pojo.User;
import com.mmall.util.CookieUtil;
import com.mmall.util.JsonUtil;
import com.mmall.util.RedisShardedPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;

@Slf4j
public class AuthorityInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object  handler) throws Exception {
        log.info("preHandle");
        //获得请求Controller的方法名
        HandlerMethod handlerMethod=(HandlerMethod) handler;
        //解析HandleMethod
        String methodName=handlerMethod.getMethod().getName();
        String className=handlerMethod.getBean().getClass().getSimpleName();
        //解析参数,具体的参数key及value是什么,打印日志
        StringBuffer requestParamBuffer = new StringBuffer();
        //
        Map paramMap=httpServletRequest.getParameterMap();
        //map.entrySet()是把HashMap类型的数据转换成集合类型
        //map.entrySet().iterator()是去获得这个集合的迭代器,保存在iterator里面
        Iterator it=paramMap.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry entry=(Map.Entry)it.next();
            String mapKey=(String)entry.getKey();
            String mapValue= StringUtils.EMPTY;
            //request这个参数mao,里面的value返回的是一个String[]
            Object obj=entry.getValue();
            if(obj instanceof String[]){
                String[] strs=(String[])obj;
                mapValue= Arrays.toString(strs);
            }
            requestParamBuffer.append(mapKey).append("=").append(mapValue);
        }

        if(StringUtils.equals(className, "UserManageController")&&StringUtils.equals(methodName,"login")){
            log.info("权限拦截器截到请求,className:{},methodName:{}",className,methodName);
            //如果是拦截到登陆请求,不打印参数,因为参数里面有密码,全部会打印到日志中,防止日志泄露
            return true;
        }
        User user=null;
        //从cookie里面获得loginToken
        String loginToken= CookieUtil.readLoginToken(httpServletRequest);
        if(StringUtils.isNotEmpty(loginToken)){
            //通过loginToken从redis里面获得用户信息
            String userJsonStr= RedisShardedPoolUtil.get(loginToken);
            //将获得的用户信息转换成对象
            user= JsonUtil.string2Obj(userJsonStr,User.class);
        }
        if(user==null||(user.getRole().intValue()!= Const.Role.ROLE_ADMIN)){
            //返回false,即不会调用controller里的方法
            httpServletResponse.reset();//这里要reset,不做这步,会报异常
            httpServletResponse.setCharacterEncoding("UTF-8");//这里需要设置编码,否则会乱码
            httpServletResponse.setContentType("application/json;charset=UTF-8");//这里需要设置返回值的类型,因为全部是json接口

            PrintWriter out=httpServletResponse.getWriter();//输出流,2种流之一

            if(user==null){
                //富文本上传判断
                if(StringUtils.equals(className,"ProdctManageCotroller")&&StringUtils.equals(methodName,"richtextImgUpload")){
                    Map resultMap= Maps.newHashMap();
                    resultMap.put("success",false);
                    resultMap.put("msg","请登陆管理员");
                    out.print(JsonUtil.obj2String(resultMap));
                }else {
                    out.print(JsonUtil.obj2String(ServerResponse.createByErrorMessage("拦截器拦截,用户未登陆")));
                }
            }else {//代表用户不是管理员
                if(StringUtils.equals(className,"ProdctManageCotroller")&&StringUtils.equals(methodName,"richtextImgUpload")) {
                    Map resultMap = Maps.newHashMap();
                    resultMap.put("success", false);
                    resultMap.put("msg", "无权限操作");
                    out.print(JsonUtil.obj2String(resultMap));
                }else{
                    out.print(JsonUtil.obj2String(ServerResponse.createByErrorMessage("拦截器拦截,用户无权限操作")));
                }
            }
            out.flush();
            out.close();//这里要关闭
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

第三步:用户管理登陆

package com.mmall.controller.backend;

import com.mmall.common.Const;
import com.mmall.common.ServerResponse;
import com.mmall.pojo.User;
import com.mmall.service.IUserService;
import com.mmall.util.CookieUtil;
import com.mmall.util.JsonUtil;
import com.mmall.util.RedisShardedPoolUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


@Controller
@RequestMapping("/manage/user")
public class UserManageController {

    @Autowired
    private IUserService iUserService;

    @RequestMapping(value="login.do",method = RequestMethod.POST)
    @ResponseBody
    public ServerResponse<User> login(String username, String password, HttpSession session, HttpServletResponse httpServletResponse){
        ServerResponse<User> response = iUserService.login(username,password);
        if(response.isSuccess()){
            User user = response.getData();
            if(user.getRole() == Const.Role.ROLE_ADMIN){
                //说明登录的是管理员
               // session.setAttribute(Const.CURRENT_USER,user);
                //新增redis共享session的方式,将sessionId以loginToken为键放到cookie里面
                CookieUtil.writeLoginToken(httpServletResponse,session.getId());
                //将sessionId为键,用户信息为值存储在redis里面
                RedisShardedPoolUtil.setEx(session.getId(), JsonUtil.obj2String(response.getData()),Const.RedisCacheExtime.REDIS_SESSION_EXTIME);
                return response;
            }else{
                return ServerResponse.createByErrorMessage("不是管理员,无法登录");
            }
        }
        return response;
    }
}
发布了241 篇原创文章 · 获赞 145 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/Richard_666/article/details/103540729
今日推荐