spring - 如何使用 LDAP 和基于角色的数据库授予权限来实现 Spring Security?
问题描述
我在 Spring MVC Thymeleaf 项目中工作,其中具有数据库和基于角色的授予权限的 LDAP 安全性是最终用户的必备要求。
我需要的
- 主要身份验证应由 LDAP 执行
- 必须在数据库中配置用户角色和授予权限以及 LDAP 用户名
example: LDAP user: nahid@test.com Role: Admin Granted Authorities for "Admin" role: permission_x,permission_y etc
将在网页中用作“hasAuthority(“permission_x”)”
- LDAP认证后,系统会检查数据库中是否存在用户为白名单用户
- 白名单检查后,为用户加载角色和权限,对加载的权限(非角色)进行授权
我发现的是这里:
https://spring.io/guides/gs/authenticating-ldap/仅显示 LDAP 身份验证。
- https://www.baeldung.com/role-and-privilege-for-spring-security-registration授予权限示例
现在我的问题是:
- 我需要用 LDAP 用户名存储 LDAP 密码吗?如果是,它安全吗?
- 上述场景是否存在任何示例?
- 细粒度的授予权限是否适用于 LDAP 用户?
LDAP 身份验证和基于 jdbc 的授权如何协同工作?有人可以帮忙吗?
提前致谢
解决方案
Since I have found a solution, I am sharing my own answer here. Hope it will help others:
My Answers are:
- No Password needs to be stored in the database.
- Not exactly
- Yes, fine-grained granted authority works perfectly for LDAP users
How I solved my problem:
Step 1:
The trick is using a UserDetailsContextMapper with UserDetails provided by regular UserDetailsService.
example:
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDetailsContextMapper(userDetailsContextMapper())
.userDnPatterns("uid={0},ou=people")
.groupSearchBase("ou=groups")
.contextSource()
.url("ldap://localhost:8389/dc=springframework,dc=org")
.and()
.passwordCompare()
.passwordEncoder(new BCryptPasswordEncoder())
.passwordAttribute("userPassword");
}
@Bean
public UserDetailsContextMapper userDetailsContextMapper() {
return new LdapUserDetailsMapper() {
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
UserDetails details= userDetailsService.loadUserByUsername(username+"@test.com");
return details;
}
};
}
After successful LDAP authentication, it will try to load valid registered user to the context with all granted authorities.
Step 2
hasAuthority didn't work for me. I have used something like below:
<div sec:authorize="hasRole('SOME_PRIVILEGE')">
<div class="alert alert-success" role="alert">
This is secret DIV
</div>
</div>
For a quick check, you can use below:
<span sec:authentication="principal.authorities"></span>
I hope it will help somebody someday.
Happy Coding!
推荐阅读
- php - 在属性注释中使用模型的问题。应该是模型而不是数组
- javascript - 如何简化具有许多条件的 IF 语句
- ansible - Ansible:找不到动态库存模块错误
- swift - 如何检查泛型类型可以快速转换为字符串
- algorithm - 检查给定树是否允许重复是二叉搜索树
- jquery - jquery切换类在componentDidMount中不起作用
- hibernate - Spring Data @OneToMany(fetch=FetchType.EAGER) 用作选择查询模式
- react-native - undefined 不是对象(评估 '_this.props.navigation') Expo React Native
- reactjs - React.js:使用 axios POST 请求填充列表框
- mobx - 去抖动 mobx-react 和 props