2012-04-17 288 views
1

UPDATE(17.04.2012):所以我得到了什麼結果。@PreAuthorize中的自定義類別委託人

根context.xml中:

<context:annotation-config/> 
<context:component-scan base-package="com.grsnet.qvs.controller.web"/> 
<security:global-method-security pre-post-annotations="enabled" /> 
<bean id="permissionManager" class="com.grsnet.qvs.auth.PermissionManager"/> 

PermissionManager.java

package com.grsnet.qvs.auth; 

import com.grsnet.qvs.model.Benutzer; 

public class PermissionManager { 

public PermissionManager() {} 

public boolean hasPermissionU01(Object principal, Integer permissionLevel) { 
    return ((Benutzer)principal).getPermission().getU_01() >= permissionLevel; 
} 
} 

控制器:

@PreAuthorize("@permissionManager.hasPermissionU01(principal, 1)") 
@RequestMapping(value = "/u01", method = RequestMethod.GET) 
public String listU01(HttpServletRequest request, Map<String, Object> map) throws Exception { 
    setGridFilters(map); 
    return "u01panel";  
} 

我設置斷點在PermissionManager.hasPermissionU01。看來我的安全註釋忽略了。

是什麼原因?我的錯誤在哪裏?

謝謝。

UPDATE

結束後google搜索我要問這裏的時間。 我

  1. 的Spring MVC應用程序
  2. CustomUserDetailService
  3. 定製的UserDetails類

    public class Benutzer extends User implements UserDetails { 
    ... 
        private Permission permission = null; 
    ... 
    } 
    
  4. 權限類,不太好實現,但我不得不使用它。

    public class Permission { 
    ... 
        private Integer u_01 = 0; 
    ... 
    } 
    
  5. 控制器

    @Controller 
    public class U01Controller { 
    
        @RequestMapping(value = "/u01", method = RequestMethod.GET) 
        public String listU01(HttpServletRequest request, Map<String, Object> map) throws Exception { 
    

我的任務是在整個確保控制器和Inside Secure的一個方法。 我想寫一些這樣的:

@PreAuthorize("principal.permission.u_01>0") 
public class U01Controller { 

@RequestMapping(value = "/u01", method = RequestMethod.GET) 
@PreAuthorize("principal.permission.u_01=2") 
public String listU01(HttpServletRequest request, Map<String, Object> map) throws Exception { 

看來ACL使用的UserDetails接口來訪問的負責人。 是否可能在ACL內部進行一些類型轉換?

@PreAuthorize("(com.grsnet.qvs.model.Benutzer)principal.permission.u_01=2") 

在此先感謝。

回答

4

雖然我認爲你可以可能這樣做(你剛剛嘗試嗎?)在我看來,最好的辦法是創建另一個類,知道如何做權限決定。特別是,它可以做這樣的:

public class Decision { 
    private Decision() {} // no instance, please 

    // Type is probably a bit too wide... 
    static boolean mayList(Object principal) { 
     return ((com.grsnet.qvs.model.Benutzer)principal).permission.u_01 == 2; 
    } 

    // etc... 
} 

那麼你@PreAuthorize可以這樣寫:

@PreAuthorize("Decision.mayList(principal)") 

如果決策過程是比較複雜的,然後你會進入使用豆做決策。然後,因爲這是春天EL,你會寫(假設你委派到decider豆):

@PreAuthorize("@decider.mayList(principal)") 

(當然,我的小Decider類以上絕對不是一個bean ...)

+0

是啊,有趣...我可以寫一些像@PreAuthorize(「Decision.mayList(主體)> 1」)?謝謝。 – mad 2012-04-17 05:43:50

+0

當然你可以,但我會去找多種方法 - 每個決定 - 每個方法返回一個布爾值。也就是說,整個決策將在該方法中進行。我願意打賭,在一個非平凡的系統中,您至少會重用一些跨業務方法的決策,並在一個地方對它們進行糾正(並且在其他地方「顯然」是正確的)對可維護性非常有價值。 – 2012-04-17 05:55:47

+0

好的,我現在看到。我會稍後再試,並會接受你的答案,否則會問你加成。謝謝。 – mad 2012-04-17 06:27:00

1

prolem解決與唐納爾的解決方案。 我的錯誤是我放在

<security:global-method-security pre-post-annotations="enabled" /> 

根上下文。

請小心,並將其放在servletContext中。

Donal,再次感謝。