java - @PreAuthorize 中的自定义类主体

标签 java spring-security

更新(2012 年 4 月 17 日):结果是这样的。

根上下文.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"/>

权限管理器.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;
}
}

Controller :

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

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

谢谢。

更新结束

经过数小时的谷歌搜索后,我不得不在这里提问。 我有

  1. Spring MVC 应用
  2. 自定义用户详细信息服务
  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 {
    

我的任务是保护整个 Controller 并保护内部方法。 我想写一些这样的:

@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 接口(interface)来访问主体。 是否可能在 ACL 中进行某种类型转换?

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

提前致谢。

最佳答案

虽然我认为您可能可以做到这一点(您刚刚尝试过吗?)但在我看来,最好的方法是创建另一个知道如何做出权限决定的类。具体来说,可以这样做:

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,您将编写(假设您委托(delegate)给 decider bean):

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

(当然,我上面的小Decider类绝对不是bean……)

关于java - @PreAuthorize 中的自定义类主体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10185400/

相关文章:

java - 使用Hibernate进行JOIN的问题

java - 当我在 Eclipse 中构建 Spring Boot 应用程序时出现异常

java - 有没有一种方法可以测量执行 SQL 查询所花费的时间而不用 Java 获取结果?

java - Spock 编译器插件无法运行,因为

java - 无法序列化 session 的 session 属性 SPRING_SECURITY_CONTEXT

spring - 如何保护个人金融网络应用程序?

java - 查找重复元素的数量并创建它们的数组

java - 从 mysql 数据库中获取值以在 JSP (JAVA) 中显示

java - Spring 5 LDAP 身份验证和 JWT token 作为响应

spring-security - Spring Data Rest:基于安全性的投影