Spring security 自定义 FilterInitationSecurityMetadataSource 实现 403 禁止问题

2023-12-02

简而言之,我正在尝试实现一个自定义 FilterInitationSecurityMetadataSource,以便使用 spring security 5.0.6 和 Spring Boot 2.0.3 在我的 Web 应用程序中动态保护/授权某些部分/URL 端点。

问题是,无论我使用什么角色,它总是给我提供禁止页面。

我已经尝试过使用不同角色名称的几种方法,并且(相信我)我已经搜索了整个互联网,甚至搜索了 Spring Security 5.0.6 书籍,但似乎没有任何效果。

这个问题可能类似于:Spring Security 动态保护 URL 的问题

下面是自定义FilterIncationSecurityMetadataSource的相关部分

public class DbFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

public Collection<ConfigAttribute> getAttributes(Object object)
        throws IllegalArgumentException {
    FilterInvocation fi=(FilterInvocation)object;
    String url=fi.getRequestUrl();

    System.out.println("URL requested: " + url);

    String[] stockArr = new String[]{"ROLE_ADMIN"};

    return SecurityConfig.createList(stockArr);
}

下面是securitywebconfigAdapter的自定义实现的相关部分

@Configuration
public class Security extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
            public <O extends FilterSecurityInterceptor> O postProcess(
                    O fsi) {
                FilterInvocationSecurityMetadataSource newSource = new DbFilterInvocationSecurityMetadataSource();
                fsi.setSecurityMetadataSource(newSource);
                return fsi;
            }
        })
        .and()
        .formLogin()
        .permitAll();
}

下面是自定义 userDetails 权限的相关部分。 用户在数据库中具有角色:ROLE_ADMIN。

public class CustomUserDetails extends User implements UserDetails {

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    List<String> dbRoles=new ArrayList<String>();
    for (Role userRole : super.getRoles()) {
        dbRoles.add(userRole.getType());
    }

    List<SimpleGrantedAuthority> authorities=new ArrayList<SimpleGrantedAuthority>();
    for (String role : dbRoles) {
        authorities.add(new SimpleGrantedAuthority(role));
    }
    return authorities;
}

我究竟做错了什么??
如果需要更多代码,请在下面评论。
如果你有好书,我可以在下面学习 Spring 安全授权的动态部分。 谢谢!


我设法通过调试进入安全流程,似乎通过创建此 SecurityConfig 类的 ConfigAttributes 是“罪魁祸首”

return SecurityConfig.createList(stockArr);
public static List<ConfigAttribute> createList(String... attributeNames) {
    Assert.notNull(attributeNames, "You must supply an array of attribute names");
    List<ConfigAttribute> attributes = new ArrayList(attributeNames.length);
    String[] var2 = attributeNames;
    int var3 = attributeNames.length;

    for(int var4 = 0; var4 < var3; ++var4) {
        String attribute = var2[var4];
        attributes.add(new SecurityConfig(attribute.trim()));
    }

    return attributes;
}

上面是该方法的实际实现,你可以看到

attributes.add(new SecurityConfig(attribute.trim()));

这总是创建 SecurityConfig 类型的实例。

在下面您可以实际看到决策是在哪里以及如何做出的。

private WebExpressionConfigAttribute findConfigAttribute(Collection<ConfigAttribute> attributes) {
    Iterator var2 = attributes.iterator();

    ConfigAttribute attribute;
    do {
        if (!var2.hasNext()) {
            return null;
        }

        attribute = (ConfigAttribute)var2.next();
    } while(!(attribute instanceof WebExpressionConfigAttribute));

    return (WebExpressionConfigAttribute)attribute;
}

因此,为了让它真正返回一个 configattribute 进行检查,它必须是 WebExpressionConfigAttribute 类型,因此永远不会出现这种情况

attributes.add(new SecurityConfig(attribute.trim()));

所以我修复它的方法是按以下方式创建我自己的 accessDecisionManager

public class MyAccessDecisionManager implements AccessDecisionManager {
@Override
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
        throws AccessDeniedException, InsufficientAuthenticationException {
    if(configAttributes == null){
        return  ;
    }
    Iterator<ConfigAttribute> ite = configAttributes.iterator();
    while(ite.hasNext()){

        ConfigAttribute ca = ite.next();

        String needRole = ((SecurityConfig)ca).getAttribute();

        for(GrantedAuthority grantedAuthority : authentication.getAuthorities()){
            if(needRole.trim().equals(grantedAuthority.getAuthority().trim())){
                return;
            }
        }
    }
    throw new AccessDeniedException("Access is denied");
}

如上所述注册,现在使用我的自定义设置 accessdecisionManager

.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
        public <O extends FilterSecurityInterceptor> O postProcess(
                O fsi) {
            FilterInvocationSecurityMetadataSource newSource = new DbFilterInvocationSecurityMetadataSource();
            fsi.setSecurityMetadataSource(newSource);
            fsi.setAccessDecisionManager(new MyAccessDecisionManager());
            return fsi;
        }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring security 自定义 FilterInitationSecurityMetadataSource 实现 403 禁止问题 的相关文章

  • Python Selenium:如何在文本文件中打印网站上的值?

    我正在尝试编写一个脚本 该脚本将从 tulsaspca org 网站获取以下 6 个值并将其打印在 txt 文件中 最终输出应该是 905 4896 7105 23194 1004 42000 放置的动物 的 HTML span class
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写
  • 如何在发布期间复制未版本化的测试资源:执行?

    我的问题与 Maven 在发布时不会复制未跟踪的资源 https stackoverflow com questions 10378708 maven doesnt copy untracked resources while releas
  • CFdump cfcomponent cfscript

    可以在 cfcomponent 中使用 cfdump 吗 可以在 cfscript 中使用 cfdump 吗 我知道 anser 不是 那么如何发出 insde cfcomponent 函数的值 cf脚本 我用的是CF8 可以在 cfcom
  • 如何在执行新操作时取消先前操作的执行?

    我有一个动作创建器 它会进行昂贵的计算 并在每次用户输入内容时调度一个动作 基本上是实时更新 但是 如果用户输入多个内容 我不希望之前昂贵的计算完全运行 理想情况下 我希望能够取消执行先前的计算并只执行当前的计算 没有内置功能可以取消Pro
  • 如何从日期中查找该月的最后一天?

    如何在 PHP 中获取该月的最后一天 Given a date 2009 11 23 我要2009 11 30 并给出 a date 2009 12 23 我要2009年12月31日 t返回给定日期所在月份的天数 请参阅的文档date ht
  • Redis如何存储关联数组?设置、散列还是列表?

    我对 Redis 的所有可用存储选项有点困惑 我想做一些简单的事情 并且不想过度设计它 我正在与phpredis and Redis v2 8 6 我有一个需要存储的简单关联数组 我还需要能够通过其键检索项目并循环遍历所有项目 a arra
  • PHPUnit 和 Zend Framework assertRedirectTo() 问题

    我在创建的测试中遇到了 assertRedirectTo 问题 下面是我使用的代码 public function testLoggedInIndexAction this gt dispatch this gt assertControl
  • 如何使用asm.js进行测试和开发?

    最近我读到asm js规范 看起来很酷 但是是否有任何环境 工具来开发和测试这个工具 这还只是处于规范阶段吗 您可以尝试使用 emscripten 和 ASM JS 1 并从侧分支在 firefox 构建中运行它 有关 asm js 的链接
  • 从超立方体图像中获取文本的确切位置

    使用 tesseract 中的 GetHOCRText 0 方法 我能够检索 html 中的文本 并在 webview 中呈现 html 时 我能够获取文本 但图像中文本的位置与输出不同 任何想法都非常有帮助 tesseract gt Se
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个
  • 用于验证目的的动态查找方法

    我正在使用 Ruby on Rails 3 0 7 我想在运行时查找一些记录以进行验证 但为该查找方法传递 设置一个值 也就是说 在我的班级中 我有以下内容 class Group lt lt ActiveRecord Base valid
  • neo4j - python 驱动程序,服务不可用

    我对 neo4j 非常陌生 我正在尝试建立从 python3 6 到 neo4j 的连接 我已经安装了驱动程序 并且刚刚开始执行第一步 导入请求 导入操作系统 导入时间 导入urllib 从 neo4j v1 导入 GraphDatabas
  • rspec 中的模拟方法链

    有一系列方法可以获得user目的 我试图模拟以下内容以返回user in my Factory Girl current user AuthorizeApiRequest call request headers result 我可以模拟该
  • 如何将输入读取为数字?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 Why are x and y下面的代码中使用字符串而不是整数 注意 在Python 2
  • NotImplementedError:无法将符号张量 (lstm_2/strided_slice:0) 转换为 numpy 数组。时间

    张量流版本 2 3 1 numpy 版本 1 20 在代码下面 define model model Sequential model add LSTM 50 activation relu input shape n steps n fe
  • 在 Nexus 7 2013 上更改方向时 CSS 媒体查询不起作用

    我目前正在我的笔记本电脑 台式电脑和 Nexus 7 2013 上测试 CSS 媒体查询 除了 Nexus 7 之外 它们在台式机和笔记本电脑上都运行良好 当我更改方向时 除非刷新页面 否则样式不会应用 例如 以纵向模式握住设备时 页面正常
  • 强制 Listview 不重复使用视图(复选框)

    我做了一个定制Listview 没有覆盖getView 方法 Listview 中的每个项目都具有以下布局 联系布局 xml

随机推荐