权限模块_使用权限_显示有权限的链接_思路分析_拦截验证每个请求的权限_完善权限的分类_一些细节

Posted 未来_我来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了权限模块_使用权限_显示有权限的链接_思路分析_拦截验证每个请求的权限_完善权限的分类_一些细节相关的知识,希望对你有一定的参考价值。

权限模块__使用权限__显示有权限的链接1__思路分析

实现功能

导入源文件,找到AnchorTag.java类复制到工程中

AnchorTag.java

package org.apache.struts2.views.jsp.ui;

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

import org.apache.struts2.components.Anchor;
import org.apache.struts2.components.Component;

import cn.itcast.oa.domain.User;

import com.opensymphony.xwork2.util.ValueStack;

/**
 * @see Anchor
 */
public class AnchorTag extends AbstractClosingTag {

    private static final long serialVersionUID = -1034616578492431113L;

    protected String href;
    protected String includeParams;
    protected String scheme;
    protected String action;
    protected String namespace;
    protected String method;
    protected String encode;
    protected String includeContext;
    protected String escapeAmp;
    protected String portletMode;
    protected String windowState;
    protected String portletUrlType;
    protected String anchor;
    protected String forceAddSchemeHostAndPort;

    @Override
    public int doEndTag() throws JspException {
        // 当前登录用户
        User user = (User) pageContext.getSession().getAttribute("user");

        // 当前准备显示的链接对应的权限URL
        // >> 在开头加上\'/\'
        String privUrl = "/" + action;

        if (user.hasPrivilegeByUrl(privUrl)) {
            return super.doEndTag(); // 正常的生成并显示超链接 标签,并继续执行页面中后面的代码
        } else {
            return EVAL_PAGE; // 不生成与显示超链接 标签,只是继续执行页面中后面的代码
        }
    }

    public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
        return new Anchor(stack, req, res);
    }

    protected void populateParams() {
        super.populateParams();

        Anchor tag = (Anchor) component;
        tag.setHref(href);
        tag.setIncludeParams(includeParams);
        tag.setScheme(scheme);
        tag.setValue(value);
        tag.setMethod(method);
        tag.setNamespace(namespace);
        tag.setAction(action);
        tag.setPortletMode(portletMode);
        tag.setPortletUrlType(portletUrlType);
        tag.setWindowState(windowState);
        tag.setAnchor(anchor);

        if (encode != null) {
            tag.setEncode(Boolean.valueOf(encode).booleanValue());
        }
        if (includeContext != null) {
            tag.setIncludeContext(Boolean.valueOf(includeContext).booleanValue());
        }
        if (escapeAmp != null) {
            tag.setEscapeAmp(Boolean.valueOf(escapeAmp).booleanValue());
        }
        if (forceAddSchemeHostAndPort != null) {
            tag.setForceAddSchemeHostAndPort(Boolean.valueOf(forceAddSchemeHostAndPort).booleanValue());
        }
    }

    public void setHref(String href) {
        this.href = href;
    }

    public void setEncode(String encode) {
        this.encode = encode;
    }

    public void setIncludeContext(String includeContext) {
        this.includeContext = includeContext;
    }

    public void setEscapeAmp(String escapeAmp) {
        this.escapeAmp = escapeAmp;
    }

    public void setIncludeParams(String name) {
        includeParams = name;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public void setScheme(String scheme) {
        this.scheme = scheme;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public void setPortletMode(String portletMode) {
        this.portletMode = portletMode;
    }

    public void setPortletUrlType(String portletUrlType) {
        this.portletUrlType = portletUrlType;
    }

    public void setWindowState(String windowState) {
        this.windowState = windowState;
    }

    public void setAnchor(String anchor) {
        this.anchor = anchor;
    }

    public void setForceAddSchemeHostAndPort(String forceAddSchemeHostAndPort) {
        this.forceAddSchemeHostAndPort = forceAddSchemeHostAndPort;
    }
}

权限模块__使用权限__拦截验证每个请求的权限

 

两个问题:拦截器怎么写,往里边写权限判断

CheckPrivilegeInterceptor.java

public class CheckPrivilegeInterceptor extends AbstractInterceptor {

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        System.out.println("-------------之前");
        String result = invocation.invoke(); //放行
        System.out.println("-------------之后");
        return result;
    }
}

struts.xml

     <interceptors>
            <!-- 声明拦截器 -->
            <interceptor name="checkPrivilege" class="cn.itcast.oa.util.CheckPrivilegeInterceptor"></interceptor>
            
            <!-- 重新定义默认的拦截器栈 -->
            <interceptor-stack name="defaultStack">
                <interceptor-ref name="checkPrivilege"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            
            </interceptor-stack>
        </interceptors>

另一种

说明拦截器可以用了,接着填充代码

struts.xml

        <!-- 全局的Result配置 -->
        <global-results>
            <result name="loginUI">/WEB-INF/jsp/userAction/loginUI.jsp</result>
            <result name="noPrivilegeError">/noPrivilegeError.jsp</result>
        </global-results>

错误页面noPrivilegeError.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<HEAD>
    <TITLE>没有权限</TITLE>
    <%@include file="/WEB-INF/jsp/public/commons.jspf" %>
</HEAD>   
<BODY>

<DIV ID="Title_bar">
    <DIV ID="Title_bar_Head">
        <DIV ID="Title_Head"></DIV>
        <DIV ID="Title"><!--页面标题-->
            <IMG BORDER="0" WIDTH="13" HEIGHT="13" SRC="${pageContext.request.contextPath}/style/images/title_arrow.gif"/> 提示
        </DIV>
        <DIV ID="Title_End"></DIV>
    </DIV>
</DIV>


<!--显示表单内容-->
<DIV ID="MainArea">
        <DIV CLASS="ItemBlock_Title1">
        </DIV> 
        
        <DIV CLASS="ItemBlockBorder" STYLE="margin-left: 15px;">
            <DIV CLASS="ItemBlock" STYLE="text-align: center; font-size: 16px;">
                出错了,您没有权限访问此功能!
            </DIV>
        </DIV>
        
        <!-- 操作 -->
        <DIV ID="InputDetailBar">
            <A HREF="javascript:history.go(-1);"><IMG SRC="${pageContext.request.contextPath}/style/images/goBack.png"/></A>
        </DIV>
</DIV>

</BODY>
</HTML>

CheckPrivilegeInterceptor.java

public class CheckPrivilegeInterceptor extends AbstractInterceptor {

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        /*System.out.println("-------------之前");
        String result = invocation.invoke(); //放行
        System.out.println("-------------之后");
        return result;*/
        
        
        //获取信息
        User user = (User) ActionContext.getContext().getSession().get("user");//当前的登录用户
        String namespace = invocation.getProxy().getNamespace();
        String actionName = invocation.getProxy().getActionName();
        
        String privUrl = namespace + actionName;//对应的权限url
        
        
        //如果未登录
        if(user == null) {
            if(privUrl.startsWith("/user_login")) {
                //如果是去登录,就放行
                return invocation.invoke();
            }else {
                //如果不是去登录,就转到登录页面
                return "loginUI";
            }
            
        }
        //如果已登录,就判断权限
        else{
            //如果有权限,就放行
            if(user.hasPrivilegeByUrl(privUrl)) {
                return invocation.invoke();
            }
            //如果没有权限,就转到提示页面
            else{
                return "noPrivilegeError";
            }
        }
    }
}

权限模块__使用权限__完善权限的分类

User.java

    /**
     * 判定本用户是否有指定url的权限
     * @param name
     * @return
     */
    public boolean hasPrivilegeByUrl(String privUrl) {
        //超级管理员有所有的权限
        if(ifAdmin()) {
            return true;
        }
        
        // >>去掉后面的参数
        int pos = privUrl.indexOf("?");
        if(pos > -1) {
            privUrl = privUrl.substring(0,pos);
        }
        
        // >>去掉UI后缀
        if(privUrl.endsWith("UI")) {
            privUrl = privUrl.substring(0, privUrl.length() - 2);
        }
        
        //如果本URL不需要控制,则登录用户就可以使用
        Collection<String> allPrivilegeUrls = (Collection<String>) ActionContext.getContext().getApplication().get("allPrivilegeUrls");
        if(!allPrivilegeUrls.contains(privUrl)) {
            return true;
        }else{
            //普通用户要判断是否含有这个权限
            for(Role role : roles) {
                for(Privilege priv : role.getPrivileges()) {
                    if(privUrl.equals(priv.getUrl())) {
                        return true;
                    }
                }
            }
            return false;
        }
    }

InitListener.java

     //准备数据:allPrivilegeUrls
        Collection<String> allPrivilegeUrls = privilegeService.getAllPrivilegeUrls(); 
        sce.getServletContext().setAttribute("allPrivilegeUrls", allPrivilegeUrls);
        System.out.println("-----------> 已准备数据 <-----------");

PrivilegeService.java

    //查询所有权限对应的URL集合(不重复)
    Collection<String> getAllPrivilegeUrls();

PrivilegeServiceImpl.java

  public Collection<String> getAllPrivilegeUrls() {
        return getSession().createQuery(
                "SELECT DISTINCT p.url FROM Privilege p WHERE p.url IS NOT NULL")
                .list();
    }

需要处理的一些细节

权限模块__解决小问题:重启Tomcat后还是登录状态

用户关联的角色权限部门都实现序列化接口

implements Serializable

权限模块__解决小问题:登录页面嵌套的问题

 

以上是关于权限模块_使用权限_显示有权限的链接_思路分析_拦截验证每个请求的权限_完善权限的分类_一些细节的主要内容,如果未能解决你的问题,请参考以下文章

权限模块_分配权限_显示树状结构_页面中的选中效果

权限模块_整体方案说明_设计实体&映射实体_实现初始化权限数据的功能

权限模块_分配权限_实现分配权限(登录与注销)的基本功能

第七课-第四讲 07_04_特殊权限SUID等详解

Django 迁移失败并显示“__fake__.DoesNotExist:权限匹配查询不存在”。

[SpringSecurity]web权限方案_自动登陆_原理分析和具体实现