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

Posted

技术标签:

【中文标题】如何使用 LDAP 和基于角色的数据库授予权限来实现 Spring Security?【英文标题】:How to implement Spring Security with LDAP and Role based granted authorities from database? 【发布时间】:2020-08-25 22:32:11 【问题描述】:

我在 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认证后,系统会检查数据库中的用户是否作为白名单用户存在 白名单检查后,将为用户加载角色和权限,并对加载的权限(非角色)进行授权

我在这里找到了:

Spring Security with LDAP and Database roles,有点过时了

https://spring.io/guides/gs/authenticating-ldap/ 仅显示 LDAP 身份验证。

https://www.baeldung.com/role-and-privilege-for-spring-security-registration 授予权限示例

现在我的问题是:

    我需要用 LDAP 用户名存储 LDAP 密码吗?如果是,是否安全? 上述场景是否存在任何示例? 细粒度的授予权限是否适用于 LDAP 用户?

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

提前致谢

【问题讨论】:

【参考方案1】:

既然我找到了解决方案,我在这里分享我自己的答案。希望对其他人有所帮助:

我的答案是:

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

我是如何解决我的问题的:

第 1 步:

诀窍是使用 UserDetailsContextMapper 和常规 UserDetailsS​​ervice 提供的 UserDetails

示例:

 @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;
            
        ;
    

LDAP 认证成功后,它会尝试将有效的注册用户加载到所有授予权限的上下文中。

第 2 步

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

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

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

<span sec:authentication="principal.authorities"></span>

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

编码愉快!

编辑: For LDAP over SSL and Spring Boot

【讨论】:

如果在 userDetailsS​​ervice.loadUserByUsername 中找不到用户怎么办 通过显示消息“未找到用户”来优雅地处理它

以上是关于如何使用 LDAP 和基于角色的数据库授予权限来实现 Spring Security?的主要内容,如果未能解决你的问题,请参考以下文章

Apache shiro:使用 ldap 进行用户身份验证,使用数据库获得角色/权限?

如何授予用户角色具有授予选项的权限?

如何查看某个角色被授予的权限

Oracle:如何授予角色读取和创建视图权限?

如何授予 SQL 角色权限以创建和管理临时表

如何枚举授予 Oracle 角色的权限列表?