使用 spring security 自定义注释

2023-12-02

我已阅读 Spring Security 文档,并了解到我可以使用以下注释来检查主题是否有权编辑用户。

@PreAuthorize("hasPermission('USER_EDIT')")
public String editUSer(User user);

我想做的是编写我的自定义注释 MyAutorizationCheck 并使用它,如下所示

@MyAuthorizationCheck(Application.USER_MANAGEMENT, AccessLevel.EDIT)
public String editUSer(User user);

其中 Application 和 AccessLevel 是枚举。

enum Application{
    USER_MANAGEMENT, ORDER_MANAGEMENT
}

enum AccessLevel{
    READ, CREATE, UPDATE, DELETE
}

此注释的处理程序应该能够决定用户是否具有权限。

有任何指示如何实现这一目标吗?

谢谢。


Spring安全使用PrePostAnnotationSecurityMetadataSource找到@PreAuthorize并将 Spring-EL 表达式转换为ConfigAttribute.

您可以实施您的MyAuthorizationCheckAnnotationSecurityMetadataSource并覆盖getAttributes将枚举转换为的方法ConfigAttribute too;

像这样写你的代码:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAuthorizationCheck {
    Application app();
    AccessLevel level();
}
public class MyAuthorizationCheckAnnotationSecurityMetadataSource extends AbstractMethodSecurityMetadataSource {

    private final PrePostInvocationAttributeFactory attributeFactory;

    public MyAuthorizationCheckAnnotationSecurityMetadataSource(PrePostInvocationAttributeFactory attributeFactory) {
        this.attributeFactory = attributeFactory;
    }

        @Override
    public Collection<ConfigAttribute> getAttributes(Method method, Class<?> targetClass) {
        if (method.getDeclaringClass() == Object.class) {
            return Collections.emptyList();
        }
        this.logger.trace(LogMessage.format("Looking for FddApi annotations for method '%s' on target class '%s'",
                method.getName(), targetClass));
        MyAuthorizationCheck myAuthorization = findAnnotation(method, targetClass, MyAuthorizationCheck.class);
        if (myAuthorization == null) {
            this.logger.trace("No expression annotations found");
            return Collections.emptyList();
        }
        Application app = myAuthorization.app();
        AccessLevel level = myAuthorization.level();
        // build the Spring-EL expression from enums
        String expr = "hasPermission('" + app.name() + "_" + level.name() + "')";
        PreInvocationAttribute pre = this.attributeFactory.createPreInvocationAttribute(null, null, expr);
        return CollUtil.newArrayList(pre);
    }
    // other method can copy from PrePostAnnotationSecurityMetadataSource
    ...

}

然后注册 MyAuthorizationCheckAnnotationSecurityMetadataSource。

我们的代码需要 PreInitationAuthorizationAdviceVoter 来检查权限,所以需要启用 prePostEnabled

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class CustomSecurityConfig extends GlobalMethodSecurityConfiguration {

    @Override
    protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
        ExpressionBasedAnnotationAttributeFactory attributeFactory = new ExpressionBasedAnnotationAttributeFactory(
                getExpressionHandler());
        return new MyAuthorizationCheckAnnotationSecurityMetadataSource(attributeFactory);
    }
}

最后你可以像这样使用@MyAuthorizationCheck:

@MyAuthorizationCheck(app = Application.USER_MANAGEMENT, level = AccessLevel.EDIT)
public String editUSer(User user);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 spring security 自定义注释 的相关文章

随机推荐

  • 动态更新 UILabel

    我有一个关于 UILabels 的问题 我什至不确定这是实现这一目标的正确方法 但我正在尝试更新 UILabel 以显示从 0 到 24 的两个数字 然后循环回零并再次显示数字序列 问题是 它需要每 1 24 秒更新一次 UILabel 这
  • NSException raise:format: 作为方法中的最后一个语句

    我有这个方法 MHTwitterParser createParser NSString format if format compare json NSOrderedSame return MHJsonTwitterParser allo
  • 如何对齐两个(或更多)图表的大小、滚动和网格

    我有三个涉及同一周期的信号 伏尔门 电流和能量 我在两张图表上打印数据 一张显示电压 蓝色 和电流 红色 另一张仅显示能量 橙色 它们是两个不同的图表 但实际上 它们共享相同的 X 轴 我有两个与鼠标移动同步的光标 充当两个图形的一个光标
  • 使用闪亮的动态CheckboxGroupInput

    我正在尝试创建一个复选框 以便能够按年份过滤数据集 然而 并非每个变量都具有每年的所有数据 因此我只想要变量具有用户界面中显示的数据的年份 遗憾的是 将我的代码拆分为条件面板后 按钮不再进行过滤 conditionalPanel condi
  • 如何使用 ui-router 将对象从 1 $state 发送到另一个 $state

    https plnkr co edit nqyBTcBgBimjkrpf2oYo p preview Expected After Login Selecting a Ticker button should make the Tags m
  • 如果元标记出现在文档正文中会发生什么?

    我正在开发一个 ASP 应用程序 代码 模板和文件的组织方式不允许我更改 body 标记之外的任何内容 所以我正在考虑在正文中插入元标记 像这样 div class dynamic content div
  • 类内友元运算符似乎不参与重载决策

    在编写允许类提供重载的 CRTP 模板时operator 基于模板参数 我发现如果类内友元运算符的参数都不属于它定义的类的类型 则该运算符似乎不会参与重载决策 煮沸 enum class FooValueT zero one two cla
  • 在 Python 中生成随机十六进制颜色

    对于 Django 应用程序 每个 成员 都被分配了一种颜色以帮助识别它们 它们的颜色存储在数据库中 然后在需要时打印 复制到 HTML 中 唯一的问题是我不确定如何生成随机数Hexpython django 中的颜色 生成 RGB 颜色很
  • 如何使用预加载器和多个图像显示加载状态?

    我正在构建一个包含数百张图像的幻灯片 并希望构建一个漂亮的加载栏 因此我的想法是使用 JavaScript 预加载图像 然后初始化 UI 的其余部分 预加载图像不是问题 但让浏览器在加载时更新状态才是问题 我已经尝试了一些方法 但浏览器只会
  • 在Rails中,是否可以限制谁可以使用api登录google?

    是否可以只允许某些谷歌帐户登录 例如 email protected 是通过谷歌托管 他们实际上是谷歌帐户 我只想要用户 mycompany能够登录这可能吗 你用 devise 还是 google api 来做这个 谢谢 如果您正在使用om
  • 当键在字典中时出现键错误

    只是试图从一堆照片的 EXIF 数据中提取一些纬度 经度信息 但代码抛出了一个KeyError即使稍后 成功 使用该键来打印特定坐标 有问题的字典是 tags GPS GPSLatitude and GPS GPSLongitude 都是键
  • NSMutableArray 中的lastObject 是否返回对象的副本?

    我有一个与这段代码相关的问题 NSNumber lastObject self myStack lastObject if lastObject self myStack removeLastObject return lastObject
  • 点击事件时清除 QLineEdit

    我正在使用给定的代码 我希望用户在 QLineEdit 小部件中输入文本 然后按复制 按钮并看到输入的文本替换了 N A 标签 我的问题是 按照此过程 如何通过简单的鼠标单击清除 QLineEdit 小部件中输入的文本 从我读到的 this
  • 旋转方法已弃用,相当于“didRotateFromInterfaceOrientation”?

    我正在尝试实施新的viewWillTransitionToSizeiOS 8 中引入的方法 所有其他旋转方法已被弃用 我想知道相当于什么didRotateFromInterfaceOrientation现在是因为我们需要执行许多清理任务 但
  • 为什么我们不能使用 new 关键字创建活动?

    为什么我们必须使用意图来启动活动 为什么我们不能使用 Activity a new Activity 启动它 我尝试在android开发者中搜索但没有得到任何答案 可以 但它不会完全初始化 Activity 上有一系列函数需要以正确的顺序调
  • Java - 私有和包私有枚举构造函数之间的区别[重复]

    这个问题在这里已经有答案了 最近我经常使用枚举 所以我想知道 私有枚举构造函数和没有任何可见性修饰符的枚举构造函数 包私有 之间有什么区别吗 枚举的构造函数是隐式的private 就像接口和注释的方法是隐式的public abstract
  • 如何在运行时正确压缩 UIImages

    我需要加载 4 个图像进行同时编辑 当我从用户库加载它们时 内存超过 500mb 并且崩溃 以下是我尝试进行任何压缩之前原始分配转储的日志 Code var pickedImage UIImage data imageData Instru
  • 如何从我的应用程序打开标准 Google 地图应用程序?

    一旦用户按下我的应用程序中的按钮 我想打开标准的 Google 地图应用程序并显示特定位置 我该怎么做 不使用com google android maps MapView 你应该创建一个Intent具有 geo URI 的对象 Strin
  • LibGDX 保存纹理以避免上下文丢失

    我的基于 LibGDX 的 Android 应用程序中有一个纹理 它是通过 FrameBuffers 按程序创建的 我需要通过上下文丢失来保留它 而且似乎唯一有效的方法就是简单地保存数据 无论是作为完整图像还是原始图像数据 输出 并在时间到
  • 使用 spring security 自定义注释

    我已阅读 Spring Security 文档 并了解到我可以使用以下注释来检查主题是否有权编辑用户 PreAuthorize hasPermission USER EDIT public String editUSer User user