春季安全jdbcAuthentication不使用默认的角色处理工作 [英] Spring security jdbcAuthentication does not work with default roles processing

查看:1767
本文介绍了春季安全jdbcAuthentication不使用默认的角色处理工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用

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

我的例子能正常工作。例如,对于

my example works fine. For example for

      http.authorizeRequests()
        // ...
        .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
        .and().formLogin()
        .and().exceptionHandling().accessDeniedPage("/Access_Denied");

如果我改变了inMemoryAuthentication春天JDBC默认 - 我有一个多角色的问题。

If I have changed inMemoryAuthentication to spring jdbc default - i got an role issue than.

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
         auth.jdbcAuthentication().dataSource(dataSource);

我确信我被配置为使用数据库和架构春天的建议(以能够使用默认的JDBC验证)。

I sure I configured db and schema using spring recommendations (to be able to use default jdbc authentication).

在调试模式下,我可以看到装载的结果从DB

In debug mode I can see result of loading from db in the

org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl
    #loadUserByUsername(username)[line 208]
    return createUserDetails(username, user, dbAuths);

在内存中的配置返回类似的结果与

It returns similar result with in memory configuration:

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)。我困惑,因为它应该为用户像之前工作。

As you can see it loads correspond Granted Authorities, but http request redirects me to .accessDeniedPage("/Access_Denied"). I confused because It should work for user like time before.

我不我的项目中使用的弹簧启动。
我的日志不包含JDBC错误的任何配置。
我花了很多时间来研究细节和我的想法刚刚完成。
你觉得我需要补充建立一些缓存库或其他什么东西?

I do not use spring boot in my project. My logs does not contain any configuration of jdbc errors. I have spend a lot of time to investigate details and my ideas have just finished. Do you think I need add to build some cache libraries or something else?

推荐答案

有2陷阱在这里打球。

首先,使用 hasRole时,('ADMIN')首先,如果它与角色preFIX(其默认是启动检查完成角色_ )如果不是在角色传递的是它preFIX(另见<一href=\"http://docs.spring.io/spring-security/site/docs/current/reference/html/el-access.html#el-common-built-in\"相对=nofollow>参考指南)。因此,在这种情况下,实际的权威检查为 ROLE_ADMIN ,而不是管理​​如您所愿/承担。

The first is that when using hasRole('ADMIN') that first a check is done if it starts with the role prefix (for which the default is ROLE_) if not the passed in role is prefix with it (see also the reference guide). So in this case the actual authority checked is ROLE_ADMIN and not ADMIN as you expect/assume.

二是在内存​​选项,使用了当角色方法不一样赘述。它检查是否在通过角色与角色preFIX开始,如果不添加它。因此,与在内存中的一个样品中,你最终与政府部门 ROLE_ADMIN ROLE_DBA

The second is that when using the in memory option the roles method does the same as mentioned here. It checks if the passed in roles start with the role prefix and if not adds it. So in your sample with the in memory one you end up with authorities ROLE_ADMIN and ROLE_DBA.

然而,在你的JDBC选项,你有当局管理​​ DBA ,因此 hasRole (管理员)检查失败,因为 ROLE_ADMIN 不等于管理​​

However in your JDBC option you have authorities ADMIN and DBA and hence the hasRole('ADMIN') check fails because ROLE_ADMIN isn't equal to ADMIN.

要解决,你有几种选择。

To fix you have several options.


  1. 而不是 hasRole 使用 hasAuthority 后者不添加角色preFIX并为中内存选项使用当局而不是角色

  2. 在JDBC选项preFIX在数据库中的当局角色_

  3. 设置默认的角色preFIX空。

  1. Instead of hasRole use hasAuthority the latter doesn't add the role prefix and for the in memory option use authorities instead of roles.
  2. In the JDBC option prefix the authorities in the database with ROLE_
  3. Set the default role prefix to empty.

首先更改内存数据库的配置使用当局而不是角色

Using hasAuthority

First change the configuration of the in memory database to use authorities instead of roles.

auth.inMemoryAuthentication()
    .withUser("dba").password("root123")
    .authorities("ADMIN","DBA");

下一个改变你的前pressions以及

next change your expressions as well

.antMatchers("/db/**").access("hasAuthority('ADMIN') and hasAuthority('DBA')")

preFIX与角色_

在该插入当局脚本preFIX与角色_ 当局。

这是一个有点棘手和中extensivly描述[迁移指南]。

This is a bit tricky and is extensivly described in [the migration guide].

有没有简单的配置选项,并要求的BeanPostProcessor ​​

There is no easy configuration option and requires a 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;
    }
}

这篇关于春季安全jdbcAuthentication不使用默认的角色处理工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆