2012-04-17 263 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,再次感谢。