gpt4 book ai didi

Spring security jdbcAuthentication 不适用于默认角色处理

转载 作者:行者123 更新时间:2023-12-01 12:29:18 25 4
gpt4 key购买 nike

使用

    @Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA");

我的例子工作正常。例如对于
      http.authorizeRequests()
// ...
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.and().formLogin()
.and().exceptionHandling().accessDeniedPage("/Access_Denied");

如果我已将 inMemoryAuthentication 更改为 spring jdbc 默认值 - 我遇到了一个角色问题。
    @Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource);

我确定我使用 spring 建议配置了 db 和 schema(以便能够使用默认的 jdbc 身份验证)。

在 Debug模式下,我可以看到从 db 加载的结果
org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl
#loadUserByUsername(username)[line 208]
return createUserDetails(username, user, dbAuths);

它返回与内存配置类似的结果:
org.springframework.security.core.userdetails.User@183a3:
Username: dba;
Password: [PROTECTED];
Enabled: true;
AccountNonExpired: true;
credentialsNonExpired: true;
AccountNonLocked: true;
Granted Authorities: ADMIN,DBA

如您所见,它加载了相应的授权机构,但 http 请求将我重定向到 .accessDeniedPage("/Access_Denied") .我很困惑,因为它应该像以前一样对用户有用。

我的项目中没有使用 spring boot。
我的日志不包含 jdbc 错误的任何配置。
我花了很多时间去调查细节,我的想法才刚刚完成。
你认为我需要添加来构建一些缓存库或其他东西吗?

最佳答案

这里有 2 个陷阱。

首先是在使用 hasRole('ADMIN') 时首先检查是否以角色前缀开头(默认为 ROLE_ ),如果不是,则传入的角色是前缀(另见 reference guide )。所以在这种情况下,实际检查的权限是ROLE_ADMIN而不是 ADMIN正如您所期望/假设的那样。

第二个是当使用 in memory 选项时 roles方法与此处提到的相同。它检查传入的角色是否以角色前缀开头,如果没有则添加它。因此,在您的内存样本中,您最终会获得权威ROLE_ADMINROLE_DBA .

但是,在您的 JDBC 选项中,您拥有权限 ADMINDBA因此 hasRole('ADMIN')检查失败,因为 ROLE_ADMIN不等于 ADMIN .

要修复,您有多种选择。

  • 而不是 hasRole使用 hasAuthority后者不添加角色前缀,对于 in memory 选项使用 authorities而不是 roles .
  • 在 JDBC 选项中,使用 ROLE_ 作为数据库中权限的前缀
  • 将默认角色前缀设置为空。

  • 使用 hasAuthority
    先把内存数据库的配置改成使用 authorities而不是 roles .
    auth.inMemoryAuthentication()
    .withUser("dba").password("root123")
    .authorities("ADMIN","DBA");

    接下来也要改变你的表情
    .antMatchers("/db/**").access("hasAuthority('ADMIN') and hasAuthority('DBA')")

    前缀为 ROLE_
    在插入权限的脚本中,权限前缀为 ROLE_ .

    删除默认角色前缀

    这有点棘手,并在 [迁移指南] 中进行了广泛的描述。

    没有简单的配置选项,需要一个 BeanPostProcessor .
    public class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
    throws BeansException {

    // remove this if you are not using JSR-250
    if(bean instanceof Jsr250MethodSecurityMetadataSource) {
    ((Jsr250MethodSecurityMetadataSource) bean).setDefaultRolePrefix(null);
    }

    if(bean instanceof DefaultMethodSecurityExpressionHandler) {
    ((DefaultMethodSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
    }
    if(bean instanceof DefaultWebSecurityExpressionHandler) {
    ((DefaultWebSecurityExpressionHandler) bean).setDefaultRolePrefix(null);
    }
    if(bean instanceof SecurityContextHolderAwareRequestFilter) {
    ((SecurityContextHolderAwareRequestFilter)bean).setRolePrefix("");
    }
    return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
    throws BeansException {
    return bean;
    }

    @Override
    public int getOrder() {
    return PriorityOrdered.HIGHEST_PRECEDENCE;
    }
    }

    关于Spring security jdbcAuthentication 不适用于默认角色处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35894206/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com