namespace 風格,system.user.useradd、system.department.add、system.common。include=false 僅節點本身、include=true 遞歸包含所有子葉子。<action path="/editSubscription"
type="org.apache.struts.webapp.example.EditSubscriptionAction"
attribute="subscriptionForm" scope="request" validate="false"
rights="system.user"> <!-- 新增權限標識 -->
<forward name="failure" path="/mainMenu.jsp"/>
<forward name="success" path="/subscription.jsp"/>
</action>
// org.apache.struts.config.ActionConfig
protected String rights = "common"; // 默認公共權限
public String getRights() { return this.rights; }
public void setRights(String rights) {
if (configured) throw new IllegalStateException("Configuration is frozen");
this.rights = rights;
}
重新編譯 struts-core.jar 或將修改類放在項目 classpath 前面覆蓋 (熱修補)。
<role name="01">
<resource-list>
<resource name="test" url="test.jsp" menu="false"/>
<resource name="user" url="user.jsp" menu="true"/>
</resource-list>
<node-list>
<node name="system.test" include="false"/> <!-- 僅節點 -->
</node-list>
</role>
| 方案 | 實現方式 | 優點 | 缺點 | 建議場景 |
|---|---|---|---|---|
| BaseAction 模式 | 所有 Action 繼承 BaseAction,在 execute() 首行調用 checkRight() | 簡單、可控、不改框架源碼 | 強制繼承、易忘調用、AOP 感弱 | 中小項目、團隊紀律較好 |
| RequestProcessor 擴展 | 繼承 RequestProcessor,覆寫 processActionPerform,在調用 Action.execute 前統一攔截 | 完全透明、零侵入、集中控制 | 需修改框架源碼/配置 controller、升級維護難 | 大型項目、嚴格合規要求 |
public class PermissionRequestProcessor extends RequestProcessor {
@Override
protected ActionForward processActionPerform(HttpServletRequest request,
HttpServletResponse response,
Action action, ActionForm form,
ActionMapping mapping) throws IOException, ServletException {
// 1. 獲取當前用戶角色權限集 (從 Session/ThreadLocal)
Set userRights = getUserRights(request);
// 2. 獲取 Action 配置的所需權限
String requiredRight = mapping.getRights(); // 需 ActionConfig 擴展支持
// 3. 判斷 (支援通配符、角色繼承邏輯)
if (!hasPermission(userRights, requiredRight)) {
// 無權限:轉發至錯誤頁或返回 403
request.setAttribute("errorMsg", "權限不足: " + requiredRight);
return mapping.findForward("accessDenied"); // 需全局 forward 配置
}
// 4. 有權限:繼續標準流程
return super.processActionPerform(request, response, action, form, mapping);
}
}
配置 struts-config.xml:<controller processorClass="com.myapp.PermissionRequestProcessor"/>
@PreAuthorize("hasAuthority('system.user')") 或 Shiro 註解,無需擴展框架核心。<intercept-url pattern="/admin/**" access="hasRole('ADMIN')"/>。rights 屬性映射到 Spring Security ConfigAttribute。FilterInvocationSecurityMetadataSource 讀取舊 XML 配置,平滑遷移。BaseAction.checkRight() 替換為註解/配置,最終移除自定義 RequestProcessor。Struts 時代的權限設計雖顯笨重,但「資源樹+角色繼承+Action 標識」的核心模型至今仍是 RBAC 系統的基石。