10.5.3 处理前端权限控制
在本系统中有些页面需要用户登录才能处理,因此系统会对这些页面进行权限检查。因此,本系统额外定义了一个控制器。该控制器检查HttpSession
中是否包含用户登录ID,如果包含登录的用户ID,则表明用户已经登录,否则提示用户登录系统。下面是用于权限检查的控制器类。
程序清单:codes\10\auction\src\org\crazyit\auction\controller\authority\AuthController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package org.crazyit.auction.controller.authority;
import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;
@Controller @RequestMapping("/auction") public class AuthController { @RequestMapping(value = "/authLogin") @ResponseBody public String preHandle(HttpSession session) throws Exception { Integer userId = (Integer) session.getAttribute("userId"); if (userId == null || userId <= 0) { return "false"; } else { return "true"; } } }
|
接下来为了让该控制器返回结果,程序会在请求页面之前先向该控制器发送请求,只有判断用户登录之后才能继续请求目标页面。下面goPage()
函数负责页面跳转功能,该函数判断被跳转页面是否需要进行权限检查,该函数的代码如下。
程序清单:codes\10\auction\WebContent\js\index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| function goPage(pager) { if (pager == "viewSucc.html" || pager == "viewOwnerItem.html" || pager == "viewBid.html" || pager == "addItem.html" || pager == "addBid.html") { $.post("auction/authLogin", {}, function(data) { if (data != "true") { $('#myModal').modal('show'); $("#tip").html( "<span style='color:red;'>您还没有登录,请先登录再执行该操作</span>"); } else { $("#data").load(pager); history.pushState(null, null, pager); } }); } else { $("#data").load(pager); history.pushState(null, null, pager); } }
|
正如上面代码所示所示,只要程序访问列出的那些页面,系统将会先判断用户是否登录,如果用户并未登录则会提示用户需要登录。
前面介绍的只是浏览器端JS的权限控制,此外还需要在前端控制器中执行权限检查。本系统考虑使用Around Advice
来进行权限控制:Around Advice
检查调用者的HttpSession
状态,如果HttpSession
包含了用户登录信息,就允许调用者调用前端处理方法;否则返回提示信息,提示用户登录。
提示:Around Advice
是AOP
编程中Advice
的一种,关于Spring AOP
、Around Advice
的内容,请参考”疯狂Java
体系”的《轻量级Java EE企业应用实战》。
该Around Advice
类的代码如下。
程序清单:codes\10\auction\src\org\crazyit\auction\controller\authority\AuthorityInterceptor.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| package org.crazyit.auction.controller.authority;
import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpSession; import org.aspectj.lang.ProceedingJoinPoint;
public class AuthorityInterceptor { public Object authority(ProceedingJoinPoint jp) throws Throwable { System.out.println("----------------------=====--------------------"); HttpSession sess = null; Object[] args = jp.getArgs(); for (int i = 0; i < args.length; i++) { if (args[i] instanceof HttpSession) sess = (HttpSession) args[i]; } Integer userId = (Integer) sess.getAttribute("userId"); if (userId == null || userId <= 0) { Map<String, String> map = new HashMap<>(); map.put("error", "您还没有登录,必须先登录才能使用该功能"); return map; } return jp.proceed(); } }
|
正如我们从上面代码所看到的,Around Advice
会检查浏览者的HttpSession
状态,如果HttpSession
中的userId
为null
或userId
的值小于0,则系统返回一个Map
对象,该对象包含了提示用户登录的信息。
定义了该Around Advice
之后,还需要将它配置在Spring
的MVC
控制器所在的容器中。
程序清单:codes\10\auction\WebContent\WEB-INF\springmvc-servlet.xml
粗体字代码指定在执行org.crazyit.auction.controller
包下任意类的系列方法之前,先调用authorityAspect
的authority()
方法,该方法用于进行权限控制:保证只有具有相应权限的浏览者才能调用前端处理方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <bean id="authority" class="org.crazyit.auction.controller.authority.AuthorityInterceptor" />
<aop:config> <aop:aspect ref="authority"> <aop:around pointcut="execution(* org.crazyit.auction.controller.*.getItemByWiner(..)) or execution(* org.crazyit.auction.controller.*.getBidByUser(..)) or execution(* org.crazyit.auction.controller.*.getItemsByOwner(..)) or execution(* org.crazyit.auction.controller.*.addItem(..)) or execution(* org.crazyit.auction.controller.*.addBid(..))" method="authority" /> </aop:aspect> </aop:config>
|