Spring security jdbcAuthentication不适用于默认角色处理
使用 我的例子很好用。例如Spring security jdbcAuthentication不适用于默认角色处理,spring,security,authentication,jdbc,role,Spring,Security,Authentication,Jdbc,Role,使用 我的例子很好用。例如 @Autowired public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA"); 如果我已经将inMemoryAuthentication更
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("dba").password("root123").roles("ADMIN","DBA");
如果我已经将inMemoryAuthentication更改为SpringJDBC默认值,那么我会遇到一个角色问题
http.authorizeRequests()
// ...
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.and().formLogin()
.and().exceptionHandling().accessDeniedPage("/Access_Denied");
我确信我使用spring建议配置了db和schema(以便能够使用默认的jdbc身份验证)
在调试模式下,我可以在
@Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource);
它返回与内存配置类似的结果:
org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl
#loadUserByUsername(username)[line 208]
return createUserDetails(username, user, dbAuths);
如您所见,它加载了相应的授权,但http请求将我重定向到.accessDeniedPage(“/Access\u Denied”)。我很困惑,因为它应该像以前一样适用于用户
我不在我的项目中使用spring boot。
我的日志不包含任何jdbc错误配置。
我花了很多时间调查细节,我的想法刚刚完成。
你认为我需要添加来构建一些缓存库或其他什么吗?这里有两个陷阱 第一个是,当使用
hasRole('ADMIN')
时,首先检查它是否以角色前缀开头(默认为role_u
),如果传入的角色不是以它为前缀(另请参见)。因此,在这种情况下,检查的实际权限是ROLE\u ADMIN
,而不是您期望/假设的ADMIN
第二个是,当使用内存选项时,roles
方法的作用与这里提到的相同。它检查传入的角色是否以角色前缀开头,如果不是,则添加它。因此,在内存中的示例中,您最终获得了权限ROLE\u ADMIN
和ROLE\u DBA
但是,在JDBC选项中,您拥有权限ADMIN
和DBA
,因此hasRole('ADMIN')
检查失败,因为ROLE\u ADMIN
不等于ADMIN
要修复此问题,您有几个选项
hasAuthority
代替hasRole
,后者不添加角色前缀,对于内存选项,使用Authority
代替roles
李>
ROLE\uuu
hasAuthority
首先更改内存数据库的配置,以使用权限
而不是角色
org.springframework.security.core.userdetails.User@183a3:
Username: dba;
Password: [PROTECTED];
Enabled: true;
AccountNonExpired: true;
credentialsNonExpired: true;
AccountNonLocked: true;
Granted Authorities: ADMIN,DBA
下一步也要改变你的表情
auth.inMemoryAuthentication()
.withUser("dba").password("root123")
.authorities("ADMIN","DBA");
前缀为角色
在插入权限的脚本中,将权限前缀为角色
删除默认角色前缀
这有点棘手,在[迁移指南]中有详细描述
没有简单的配置选项,需要BeanPostProcessor
.antMatchers("/db/**").access("hasAuthority('ADMIN') and hasAuthority('DBA')")
您可以看到启用日志记录时发生了什么。在
应用程序.properties中添加:
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;
}
}
不,不应该。。。当使用in-memroy数据库时,角色会自动以ROLE_uu
作为前缀(默认角色前缀)。这同样适用于hasRole('ADMIN')
,它还将检查传入的角色是否有前缀,如果没有前缀,将添加该角色。您的用户拥有权限ADMIN
而不是ROLE\u ADMIN
,因此检查失败。使用hasAuthority
而不是hasRole
(并在内存样本中将roles
更改为authorities
),或者在数据库中的权限前面加上ROLE\uu
前缀,或者将默认角色前缀改为空而不是ROLE\uu
。非常感谢!现在可以了。你能在角色比较的地方添加链接吗(我希望这些信息在不久的将来对我有用)?
# ==============================================================
# = Logging springframework
# ==============================================================
logging.level.org.springframework.jdbc=DEBUG
logging.level.org.springframework.security=DEBUG
logging.level.org.springframework.web=DEBUG
logging.level.org.springframework.http=DEBUG