@PreAuthorize中的自定义类主体

时间:2012-04-17 05:08:37

标签: java spring-security

更新(2012年4月17日):所以我得到了结果。

根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中设置了断点。似乎我的安全注释被忽略了。

是什么原因?我的错误在哪里?

感谢。

END OF UPDATE

经过几个小时的谷歌搜索,我不得不问这里。 我有

  1. Spring MVC app
  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 {
    
  6. 我的任务是整体保护控制器并确保内部方法的安全。 我想写一些这样的:

    @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")
    

    提前致谢。

2 个答案:

答案 0 :(得分: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)")

如果决策过程更复杂,那么您将开始使用bean来做决策。然后,因为这是Spring EL,你会写(假设你委托给decider bean):

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

(当然,上面我的小Decider课肯定不是豆...)

答案 1 :(得分:1)

用Donal的解决方案解决了问题。 我的错误是我放置了

<security:global-method-security pre-post-annotations="enabled" />
上下文中。

小心它并将其放在servletContext中。

多纳,再次感谢。