1. 程式人生 > >權限模塊_使用權限_顯示有權限的鏈接_思路分析_攔截驗證每個請求的權限_完善權限的分類_一些細節

權限模塊_使用權限_顯示有權限的鏈接_思路分析_攔截驗證每個請求的權限_完善權限的分類_一些細節

sca tomcat jsp getname stack string struts2 ava stand

權限模塊__使用權限__顯示有權限的鏈接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

權限模塊__解決小問題:登錄頁面嵌套的問題

技術分享

技術分享

權限模塊_使用權限_顯示有權限的鏈接_思路分析_攔截驗證每個請求的權限_完善權限的分類_一些細節