1. 程式人生 > >SSH開發 | 配合自定義註解 和 Stratus攔截器,實現 方法級粒度 用戶鑒權

SSH開發 | 配合自定義註解 和 Stratus攔截器,實現 方法級粒度 用戶鑒權

struts OS action gin 所有 具體實現 getmethod red nal

1.提要

  本文是 小小商城-SSH版的 細節詳解系列 之一,項目 github:https://github.com/xenv/S-mall-ssh 本文代碼大部分在 github 中 可以找到。

  有用戶系統,就必須有配套的鑒權系統來確保頁面不被非法訪問。市面上的鑒權系統,最為成熟的就是shiro,但是體量太重,使用也不太方便,對代碼的侵入型也比較強,所以我簡單使用 自定義註解 和 Stratus攔截器 就實現了一個 簡單 的鑒權系統,雖然不及 shiiro 穩定和功能強大,但是也足夠使用,並且配置非常簡單。

2.具體實現

  原理其實非常簡單,先在 action 類和 方法上配置好自定義註解,然後配置一個攔截器讀取這些註解,在和 session

裏面的 user 比對 權限,判斷是否放行即可。

  在配置自定義註解時,我選擇了類和方法同時配置,方法如果不配置則使用類的權限配置。

  1. 在User實體類中,用enum定義用戶組

 public enum Group{
        unLogin,user,admin,superAdmin;
 }

  2. 定義一個自定義註解

@Retention(RetentionPolicy.RUNTIME) // 運行時可以被獲取
@Target({METHOD,TYPE}) //加載類上或者方法上面
@Inherited //可以子類繼承
public @interface Auth {
    User.Group value(); 
//User.Group是一個enum類型,在User實體類中定義 }

  3. 在 action 類中加入這個自定義註解

  比如前臺的 Action 中,可以在 action 類上面加一個 @Auth(User.Group.unLogin) ,這樣該 action 類下面的所有方法 unLogin 用戶都可以訪問。對於不想要 unLogin 用戶 訪問 的方法,可以在那個方法上面加上 @Auth(User.Group.user) ,就會覆蓋掉 類的權限配置。

  4.配置一個攔截器實現鑒權動作

public class AuthInterceptor extends AbstractInterceptor {
    @Override
    
public String intercept(ActionInvocation actionInvocation) throws Exception { //獲取訪問頁面的權限 //獲取方法上的註解 Object action =actionInvocation.getAction(); String methodName=actionInvocation.getProxy().getMethod(); Auth authInMethod=action.getClass().getMethod(methodName).getAnnotation(Auth.class); //獲取類上的註解 Auth authInClass = action.getClass().getAnnotation(Auth.class); //獲取Enum方法的ordinal,根據大小來確定該頁面權限 int pageRate = authInClass==null?0:authInClass.value().ordinal(); pageRate = authInMethod == null?pageRate:authInMethod.value().ordinal(); //獲取用戶的權限 int userRate = 0; User user = (User) ActionContext.getContext().getSession().get("user"); if(user!=null){ userRate = user.getGroup().ordinal(); } //根據權限決定是否放行 if(pageRate>userRate){ if(userRate == 0) { ServletActionContext.getResponse().sendRedirect("/login"); return null; } return "/noAuth"; } return actionInvocation.invoke(); } }

  5.使攔截器生效,在struts.xml中配置

    <package name="basic-struts" extends="struts-default">
        <interceptors>
            <interceptor name="authInterceptor" class="tmall.interceptor.AuthInterceptor" />

            <interceptor-stack name="myInterceptors">
                <interceptor-ref name="authInterceptor"/>
                <interceptor-ref name="defaultStack"/>
            </interceptor-stack>
        </interceptors>
        <default-interceptor-ref name="myInterceptors" />
        <global-results>
            <result name="/noAuth">/noAuth</result>
        </global-results>
    </package>

  OK,大功告成。

SSH開發 | 配合自定義註解 和 Stratus攔截器,實現 方法級粒度 用戶鑒權