@PreAuthorize 和 hasPermission() 执行代码两次

2023-12-24

我想使用 @PreAuthorize Spring 注释来控制应用程序中的访问。

问题是,我有很多条件不取决于请求参数,而是取决于数据库实体。

概述:

我有一个Route实体,具有User owner场地。您可以删除Route仅当您是所有者时。

我已经写了我的控制器方法:

@RequestMapping(value = "/route/remove/{id}", method = RequestMethod.GET)
@PreAuthorize("hasPermission(#id, 'RouteRemove')")
  public String removeRoute(@PathVariable("id") Integer id, ModelMap model) {

  Route route = routeBO.getById(id);

  if(null == route)
    return "forward:/errors/404";

  // ... remove route here.
  // routeBO.remove(id);
}

My RouteRemove权限定义为:

@Component
public class RouteRemovePermission implements Permission {

    @Autowired
    private RouteBO routeBO;

    @Override
    public boolean isAllowed(Authentication authentication, Object targetDomainObject) {
        if(!(targetDomainObject instanceof Integer))
            return false;

        Route route = routeBO.getById((Integer) targetDomainObject);

        if(route == null)
            return false;

        User user = AthenticationUtil.getUser();

        return null != user && user.equals(route.getOwner());
    }

}

正如你所看到的,我必须评估routeBO.getById() twice.

问题:

是否可以只评估此代码一次?

当然我已经尝试过了:

@RequestMapping(value = "/route/remove/{id}", method = RequestMethod.GET)
public String removeRoute(@PathVariable("id") Integer id, ModelMap model) {

Route route = routeBO.getById(id);

if(null == route)
  return "forward:/errors/404";

return removeRoute(route, model);
}

@PreAuthorize("hasPermission(#id, 'RouteRemove')")
public String removeRoute(Route id, ModelMap model) {

    return "route/display";
}

但之前没有调用permission方法removeRoute(Route id, ModelMap model)。也许我的配置不正确?

mvc-dispatcher-servlet.xml

<sec:global-method-security secured-annotations="enabled" pre-post-annotations="enabled">
  <sec:expression-handler ref="expressionHandler"/>
</sec:global-method-security>

安全性.xml

<beans:bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <beans:property name="permissionEvaluator" ref="permissionEvaluator"/>
</beans:bean>

<beans:bean id="permissionEvaluator" class="pl.wsiadamy.common.security.BasePermissionEvaluator">
  <beans:constructor-arg index="0">
        <beans:map key-type="java.lang.String"
             value-type="pl.wsiadamy.common.security.Permission">
            <beans:entry key="RouteView" value-ref="routeViewPermission" />
            <beans:entry key="RouteRemove" value-ref="routeRemovePermission" />
        </beans:map>
    </beans:constructor-arg>
</beans:bean>
<beans:bean id="routeViewPermission" class="pl.wsiadamy.common.security.permission.RouteViewPermission" />
<beans:bean id="routeRemovePermission" class="pl.wsiadamy.common.security.permission.RouteRemovePermission" />

我建议您将安全注释的removeRoute方法分解为单独的服务类,例如:

@Service
public class RouteService {
    @PreAuthorize("hasPermission(#route, 'RouteRemove')")
    public void removeRoute(Route route) {
        // remove route here
    }
}

然后你在你的网络控制器中使用它:

@Autowired RouteService routeService;

@RequestMapping(value = "/route/remove/{id}", method = RequestMethod.GET)
public String removeRoute(@PathVariable("id") Integer id, ModelMap model) {
    Route route = routeBO.getById(id);
    if(null == route)
        return "forward:/errors/404";
    routeService.removeRoute(route);
    return "route/display";
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

@PreAuthorize 和 hasPermission() 执行代码两次 的相关文章

随机推荐

  • 计算 PostgreSQL 中字符串中子字符串出现的次数

    如何计算 PostgreSQL 中字符串中子字符串出现的次数 Example 我有一张桌子 CREATE TABLE test user uid integer NOT NULL name text result integer CONST
  • iOS10 UNNotificationServiceExtension 未调用

    我正在实施新的 iOS10 扩展以使用丰富的通知 我试图在推送通知上测试它 但不起作用 我只是收到一个简单的通知 并且没有经历扩展 我做了官方网站和其他一些地方指定的所有操作 我的应用程序已启动并运行 并带有推送通知和正确的配置文件 我向我
  • 同步 Mercurial 存储库集合

    我在网络共享上有一组 Mercurial 存储库 为了启用离线工作 我需要在我的笔记本电脑上保存该集合的本地副本 以及在在线时同步这两个集合的简单方法 为此 我编写了一个快速脚本 自动将每个本地存储库与相应的远程存储库同步 推和拉 但它缺少
  • 清理本机反应项目

    如何清理反应本机项目 有什么方法可以像清理 xcode 项目一样清理 React Native 项目吗 任何帮助将不胜感激 一个反应原生项目是关于一个Xcode项目和一个安卓项目 对于纯js代码 不需要clean 所以 你需要的是 清理 X
  • 使用 Javascript 在帧之间传递数据

    我已经设置了一个简单的例子http ryanmalin co uk frames http ryanmalin co uk frames 如果您按 添加 它将把左侧框架中的表单数据粘贴到右侧框架中 当我将正确的框架 URL 更改为另一个域的
  • 在 JAX-RS Provider 中使用 @Context 向 CDI bean 提供上下文信息

    我有一些网络服务 JAX RS WildFly 9 Resteasy RequestScoped public class SomeService operations 现在我想提取上下文信息 例如用户代理 这可以使用 Context pr
  • jQuery - 从所选选项获取自定义属性

    鉴于以下情况
  • 使用批处理脚本附加文件夹名称并加 1

    我对批处理脚本的这一部分有点陌生 但我想做的是附加一堆文件夹名称并递增 1 同时尊重时间戳 即最新的文件夹在前 最旧的文件夹在最后 我看过其他脚本没有效果 Before Folder 1 Folder 2 Folder 3 Folder 4
  • 仅在时间序列中填充有限数量的 NA

    有什么办法可以让我们填补NAs in a zoo or xts数量有限的对象NA向前 换句话说就像填充NA最多连续 3 个NAs 然后保留NA从第 4 个值开始直到有效数字 像这样的东西 library zoo x lt zoo 1 20
  • 自动布局 UILabels

    我有三个UILabels按照我的习惯UITableViewCell 这可能是一些UILabels将是空的 label text UITableViewCell tableView UITableView tableView cellForR
  • 在 R 中为逻辑回归模型绘制多条 ROC 曲线

    我有一个逻辑回归模型 使用 R 作为 fit6 lt glm formula survived ascore gini failed data records family binomial summary fit6 我在用着pROC用于绘
  • Javascript通知解决方案库:桌面、声音、弹出、标题栏闪烁等

    是否有任何 Javascript 库支持在长时间运行的操作 例如上传 结束时发出通知 通知最好是通用的 这样即使某些技术不起作用 例如桌面通知 浏览器仍然能够引起注意 声音铃声 桌面通知 Chrome Stackoverflow com 风
  • 在Python中解析JSON时出现各种错误

    尝试从需要登录的 url 解析 json 在这里包括我的所有代码 因为我不确定错误在哪里 try import simplejson as json except ImportError import json import urllib2
  • 使用 .after() 添加 html 关闭和打开标签

    我试图通过找到列表的中间点并添加将无序列表分成两列 ul 在那之后 这可能是完全错误的方法 但这是我的想法 我的js看起来像这样 container ul each function var total this children leng
  • 有没有办法在 Racket 中查看 lambda 的主体?

    假设我有这段代码 lang racket define a x x y y z w w z 我凭直觉知道这个 lambda 表达式 扩展地 等于 z z 我的问题是是否有办法打印出正文a如果我想看看 Racket 在内部简化了多少功能 更多
  • 如何从数组元素中删除字符?

    我有一个像这样的数组 ee 3 4 22 22 我想删除逗号 或将其替换为 34使数组看起来像这样 ee 3 4 22 22 or this ee 3 4 34 22 34 22 34 原因是我试图将该数组从 Ruby 传递到 JavaSc
  • Asp Core 发布时错误的程序集重定向

    使用 Visual Studio 发布我的 ASP Core 项目时 config文件与我的可执行文件一起创建 The config包括几个bindingRedirect像这样
  • NIO SocketChannel 读取超时? [复制]

    这个问题在这里已经有答案了 如果连接建立后一段时间内没有收到数据 设置超时关闭 NIO SocketChannel 的最佳方法是什么 Either 您正在使用一个Selector 在这种情况下 您可以选择一个可以使用的超时 如果超时 sel
  • 如何手动创建 Apache Windows 服务

    我在尝试安装另一个 Apache Web 服务器时不小心删除了 Apache Windows 服务 有谁知道如何从 cmd 创建另一个 Apache Windows 服务 我尝试了 sc create 但最后缺少一个脚本 例如 k star
  • @PreAuthorize 和 hasPermission() 执行代码两次

    我想使用 PreAuthorize Spring 注释来控制应用程序中的访问 问题是 我有很多条件不取决于请求参数 而是取决于数据库实体 概述 我有一个Route实体 具有User owner场地 您可以删除Route仅当您是所有者时 我已