如何使用 LDAP 和基于角色的数据库授予权限实现 Spring Security?

mnh*_*ilu 3 spring ldap spring-mvc spring-security spring-boot

我在 Spring MVC Thymeleaf 项目中工作,其中具有数据库和基于角色的授予权限的 LDAP 安全性是最终用户的必备要求。

我需要的

  • 主要身份验证应由 LDAP 执行
  • 必须在数据库中配置用户角色和授予的权限以及 LDAP 用户名
example: 
LDAP user: nahid@test.com
Role: Admin
Granted Authorities for "Admin" role: permission_x,permission_y etc
Run Code Online (Sandbox Code Playgroud)

它将在网页中用作“hasAuthority(“permission_x”)”

  • LDAP 认证后,系统会检查用户是否作为白名单用户存在于数据库中
  • 白名单检查后,将为用户加载角色和权限,并对加载的权限(不是角色)进行授权

我发现的是在这里:

现在我的问题是:

  1. 我是否需要使用 LDAP 用户名存储 LDAP 密码?如果是,安全吗?
  2. 上述情况是否有任何示例?
  3. 细粒度的授予权限是否适用于 LDAP 用户?

LDAP 身份验证和基于 jdbc 的授权将如何协同工作?有人可以帮忙吗?

提前致谢

mnh*_*ilu 5

由于我找到了解决方案,我在这里分享我自己的答案。希望它会帮助其他人:

我的回答是:

  1. 无需将密码存储在数据库中。
  2. 不完全是
  3. 是的,细粒度的授予权限非常适合 LDAP 用户

我如何解决我的问题:

第1步:

诀窍是使用的UserDetailsContextMapper的UserDetails定期提供的UserDetailsS​​ervice

例子:

 @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;
            }
        };
    }
Run Code Online (Sandbox Code Playgroud)

成功通过 LDAP 身份验证后,它将尝试将有效的注册用户加载到具有所有授予权限的上下文中。

第2步

hasAuthority对我不起作用。我使用过类似下面的东西:

<div sec:authorize="hasRole('SOME_PRIVILEGE')">
            <div class="alert alert-success" role="alert">
                This is secret DIV
            </div>
        </div>
Run Code Online (Sandbox Code Playgroud)

为了快速检查,您可以使用以下内容:

<span sec:authentication="principal.authorities"></span>
Run Code Online (Sandbox Code Playgroud)

我希望有一天它会帮助某人。

快乐编码!

编辑: 对于 LDAP over SSL 和 Spring Boot