相比于shiro、security这种专门的安全框架而言,如果只是单纯的想对页面按钮实现权限控制,那么使用tld标签扩展的功能 就可以实现。主要是配置少、轻量级、方便实现的优点 让我选择了它。但缺点是 只能在JSP页面中使用。
首先创建tld标签配置文件
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- 标签库描述符 -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
<description> Tag 1.0 library</description><!--对taglib的描述-->
<display-name> Tag</display-name> <!--显示的名字-->
<tlib-version>1.0</tlib-version><!--版本-->
<jsp-version>1.2</jsp-version><!--版本-->
<!--上面的4个配置 可要可不要 不强制 都有默认值-->
<short-name>sl</short-name> <!--引用标签时的前缀-->
<uri>/test</uri> <!--用来之后引用taglib时的url 没什么特别含义-->
<tag>
<!-- 标签名 -->
<name>auth</name>
<!-- 标签实例化的实体类地址 需要全限命名 -->
<tag-class>com.llf.Util.TagConfig</tag-class>
<!-- 标签的内容类型:empty表示空标签(使用空标签会报错,不能加入值),jsp表示可以为任何合法的JSP元素 -->
<body-content>JSP</body-content>
<attribute>
<!--标签的参数名-->
<name>code</name>
<!--是否必要 建议为true-->
<required>true</required>
<!--是否允许表达式取值-->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
这个文件可以放在WEB-INF
下的任意位置 但必须在wen-inf目录下 否则无法加载
创建tld标签配置实体类
package com.llf.Util;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.io.IOException;
/**
* @Author llf
* @Date 2021/12/6 10:38
* @Version 1.0
*/
public class TagConfig extends BodyTagSupport {
private String code;
public Object getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
/**
* 标签的开始
//SKIP_BODY 从开始直接结束不走身体部分 就是不现实标签中的文字
super.doStartTag()默认SKIP_BODY
//EVAL_BODY_INCLUDE 显示标签中的文字
*/
@Override
public int doStartTag() throws JspException {
HttpSession session = pageContext.getSession();
Integer roles = (Integer) session.getAttribute("userRoles");
if (this.code!=null&&this.code.equals(roles)){
return 1;
}else {
return 0;
}
}
}
/* *//**
* 标签的结束
*//*
//SKIP_PAGE 结束后面的标签执行 直接到HTML的闭签
//EVAL_PAGE 则是显示标签执行
// super.doEndTag()
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
return EVAL_PAGE;
}*/
页面引入标签 进行权限判断
<%--自定义标签引入--%>
<%@ taglib prefix="sl" uri="/test"%>
<%--使用标签将需要判断的元素包裹--%>
<sl:auth code="1">
<span><a class="modifyUser"
href="${pageContext.request.contextPath}/toupdate?id=${user.id}">
<img src="${pageContext.request.contextPath }/images/xiugai.png"
alt="修改" title="修改"/></a></span>
<span><a class="deleteUser">
<img src="${pageContext.request.contextPath }/images/schu.png"
alt="删除" id="${user.id}"
nclick="remove(this);" title="删除"/></a></span>
</sl:auth>
如果userRoles与code的值相等 就返回1 显示这些信息 反之不显示
使用ThreadLocal类存取user信息
如果使用session存储用户信息 我们在后端每次调用都需要引用HttpServletRequest
来实现,这样的实现方法比较麻烦。因此我们可以使用ThreadLocal类存取user信息
package com.llf.Util;
import com.llf.Pojo.User;
import org.springframework.http.HttpRequest;
import javax.servlet.http.HttpServletRequest;
/**
* @Author llf
* @Date 2021/12/6 13:51
* @Version 1.0
*/
public class RequestHolder {
private static final ThreadLocal<User> userHolder = new ThreadLocal<User>();
private static final ThreadLocal<String> requestHolder = new ThreadLocal<String>();
public static void set(User user) {
userHolder.set(user);
}
public static void set(String request) {
requestHolder.set(request);
}
public static User getCurrentUser(){
return userHolder.get();
}
public static String getCurrentRequest() {
return requestHolder.get();
}
public static void remove() {
userHolder.remove();
requestHolder.remove();
}
}
这个类可以存储当前的访问地址,当前用户的基本信息
然后在filter拦截器中引用这个方法 对user和uri进行赋值
package com.llf.Filter;
import com.llf.Pojo.User;
import com.llf.Util.RequestHolder;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class MyFilter implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
if (user != null) {
if (RequestHolder.getCurrentUser()==null){
RequestHolder.set(user);
}
RequestHolder.set(request.getRequestURI());
return true;
}
if (request.getRequestURI().contains("index")) {
return true;
}
if (request.getRequestURI().contains("login")) {
RequestHolder.set(request.getRequestURI());
return true;
}
request.getRequestDispatcher("/WEB-INF/jsp/error.jsp").forward(request, response);
return false;
}
}
这样就可以在任何地方拿到user信息了 并且不需要进行session的引入 还是比较方便的