简体   繁体   English

Spring LDAP角色映射

[英]Spring LDAP role mappings

I followed this article and configured my application to authenticate via LDAP (that's working perfectly). 我遵循了这篇文章,并将我的应用程序配置为通过LDAP进行身份验证(运行良好)。 Now I'm using in application just 3 roles and I would like to create mapping for them. 现在,我仅在应用程序中使用3个角色,我想为其创建映射。

So I implemented interface GrantedAuthoritiesMapper 所以我实现了接口GrantedAuthoritiesMapper

@Component
public class MyAuthorityMapper implements GrantedAuthoritiesMapper {

    @Autowired
    private MyAuthorityConfig authoritiesConfig;

    @Override
    public Collection<? extends GrantedAuthority> mapAuthorities(Collection<? extends GrantedAuthority> collection) {
        Set<MyAuthority> roles = EnumSet.noneOf(MyAuthority.class);

        for (GrantedAuthority g : collection) {
            for (String role : authoritiesConfig.getAuthoritiesMap().keySet()) {
                if (Arrays.asList(authoritiesConfig.getAuthoritiesMap().get(role).split(",")).contains(g.getAuthority())) {
                    roles.add(MyAuthority.valueOf(role));
                }
            }
        }
        return roles;
    }
}

Here is role populator 这是角色填充器

@Component
@ConfigurationProperties(prefix = "auth.role.mapping")
public class MyAuthorityConfig {

    private Map<String, String> authroritiesMap = new HashMap<String, String>();

    public Map<String, String> getAuthoritiesMap() {
        return this.authroritiesMap;
    }
}

and application-dev.properties 和application-dev.properties

auth.role.mapping.ROLE_COMPETENCE_CENTER=ROLECC
auth.role.mapping.ROLE_OPERATIONS=ROLEOPS,ROLEPAR
auth.role.mapping.ROLE_ADMINISTRATOR=ROLEADM,ROLESUPUSR

Now MyAuhtorityConfig contains only empty map. 现在,MyAuhtorityConfig仅包含空映射。 Is it possible to use @ConfigurationProperties like I'm using it here? 是否可以像在此使用@ConfigurationProperties一样使用它? I can't find how to populate map with it. 我找不到如何用它来填充地图。 Or is there issue with profile specific properties file? 还是特定于配置文件的属性文件存在问题?

In WebSecurityConfig I have method for LDAP config but I don't know how/where to inject MyAuthorityMapper or if it's even possible without using ActiveDirectoryLdapAuthenticationProvider 在WebSecurityConfig中,我有用于LDAP配置的方法,但是我不知道如何/在何处注入MyAuthorityMapper或者即使不使用ActiveDirectoryLdapAuthenticationProvider也不可能

private void configureLdap(AuthenticationManagerBuilder auth) throws Exception {
        DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(env.getProperty("auth.ldap.urls"));
        contextSource.setUserDn(env.getProperty("auth.ldap.user"));
        contextSource.setPassword(env.getProperty("auth.ldap.password"));
        contextSource.setReferral("follow");
        contextSource.afterPropertiesSet();

        auth.ldapAuthentication()
                .userSearchBase(env.getProperty("auth.ldap.user.search.base"))
                .userSearchFilter(env.getProperty("auth.ldap.user.search.filter"))
                .groupSearchBase(env.getProperty("auth.ldap.group.search.base"))
                .groupSearchFilter(env.getProperty("auth.ldap.group.search.filter"))
                .groupRoleAttribute(env.getProperty("auth.ldap.group.search.attribute"))
                .contextSource(contextSource)
                ;
    }

Ok so for first issue with @ConfigurationProperties there is fix like this: 好的,因此对于@ConfigurationProperties第一个问题,有如下修复方法:

@Component
@ConfigurationProperties(prefix = "auth.role")
public class MyAuthorityConfig {

    private Map<String, String> mapping = new HashMap<String, String>();

    public Map<String, String> getMapping() {
        return this.mapping;
    }
}

@ConfigurationProperties look for prefix auth.role in properties and then get the mapping part which should be the name of property in my class. @ConfigurationProperties在属性中查找前缀auth.role,然后获取映射部分,该部分应该是我的类中属性的名称。

For second issue I found solution with UserDetailsContextMapper 对于第二个问题,我找到了UserDetailsContextMapper解决方案

@Component(value = "myUserDetailsContextMapper")
public class MyUserDetailsContextMapper implements UserDetailsContextMapper {

    private static final Logger log = LoggerFactory.getLogger(MyUserDetailsContextMapper.class);

    @Autowired
    private MyAuthorityConfig authoritiesConfig;

    @Override
    public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<? extends GrantedAuthority> authorities) {
        log.debug("mapUserFromContext start");
        List<GrantedAuthority> mappedAuthorities = new ArrayList<>();

        for (GrantedAuthority g : authorities) {
            for (String role : authoritiesConfig.getMapping().keySet()) {
                if (Arrays.asList(authoritiesConfig.getMapping().get(role).split(","))
                        .contains(g.getAuthority().startsWith("ROLE_") ? g.getAuthority().substring("ROLE_".length()) : g.getAuthority())) {
                    log.debug("Mapping from LDAP role {} to application role {} for user {}", g.getAuthority(), role, username);
                    mappedAuthorities.add(MyAuthority.valueOf(role));
                }
            }
        }

        return new User(username, "", mappedAuthorities);
    }

    @Override
    public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {

    }
}

I'm not sure if returning just new User(username, "", mappedAuthorities); 我不确定是否仅返回new User(username, "", mappedAuthorities); is ok (I must test it properly with locked/disabled users) but for now it works. 可以(我必须对锁定/禁用的用户进行正确的测试),但现在可以使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM