问题描述
使用
@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(另见参考指南)。因此,在这种情况下,实际的权威检查为 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.
- 而不是
hasRole
使用hasAuthority
后者不添加角色preFIX并为中内存选项使用当局
而不是角色
。 - 在JDBC选项preFIX在数据库中的当局
角色_
- 设置默认的角色preFIX空。
- Instead of
hasRole
usehasAuthority
the latter doesn't add the role prefix and for the in memory option useauthorities
instead ofroles
. - In the JDBC option prefix the authorities in the database with
ROLE_
- 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不使用默认的角色处理工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!