如何通过ldap Spring 3.0进行身份验证后获取Active Directory组?

时间:2013-03-19 15:01:56

标签: java active-directory spring-security ldap

我正在构建一些已经开发的代码,并且已经被要求通过ldap进行身份验证,我可以这样做但是现在我被要求根据Active Directory组设置权限。问题是我不确定如何采取我所拥有的并在此基础上进行构建。我在Spring中没有经验,我曾尝试(但没有成功)从头开始使用Active Directory使用包括[this] [1]在内的一些教程,我寻求帮助[这里] [2]和[这里] [3]但没有成功。首先我不能使用spring 3.1,我们只能使用3.0,而且我在修改上面提到的任何例子方面都没有成功。

我有没有办法从我已经获得的Active Directory组(和其他属性)? 以下是我到目前为止所做的事情:

弹簧security.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans" xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">
    <http auto-config="true" use-expressions="true">
        <intercept-url pattern="/login" access="permitAll" />
        <intercept-url pattern="/loginfailed" access="permitAll" />
        <intercept-url pattern="/resources/images/**" access="permitAll" />
        <intercept-url pattern="/resources/css/**" access="permitAll" />
        <intercept-url pattern="/**" access="hasRole('CUSTOMADMIN')" />
        <form-login login-page="/login" default-target-url="/index" authentication-failure-url="/loginfailed" />
        <logout logout-success-url="/logout" />
    </http>
    <ldap-server id="ldapServer" url="ldap://url:portnumber/ou=People,dc=abc,dc=com" manager-dn="dn" manager-password="password" />
    <authentication-manager>
        <authentication-provider ref="ldapAuthProvider" />
    </authentication-manager>
    <beans:bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
        <beans:constructor-arg>
            <beans:bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
                <beans:constructor-arg ref="ldapServer" />
                <beans:property name="userDnPatterns">
                    <beans:list>
                        <beans:value>uid={0}</beans:value>
                    </beans:list>
                </beans:property>
            </beans:bean>
        </beans:constructor-arg>
        <beans:constructor-arg>
            <beans:bean class="com.company.group.appname.ldap.RolesPopulator">
                <beans:constructor-arg ref="userRoleService" />
            </beans:bean>
        </beans:constructor-arg>            
</beans:beans>

RolesPopulator.java

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator;

import com.company.group.appname.service.IUserRoleService;

public class RolesPopulator implements LdapAuthoritiesPopulator 
{
    private static Logger log = Logger.getLogger(RolesPopulator.class);
    @Autowired
    private IUserRoleService userRoleService;

    public RolesPopulator(IUserRoleService userRoleService)
    {
       this.userRoleService = userRoleService;
    }

    @Override
    public Collection<GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username) 
    {
        List<GrantedAuthority> userPerms = new ArrayList<GrantedAuthority>();
        log.debug("UserPermsions: "+userPerms.toString());

        //get users permissions from service
        List<String> userRoles = userRoleService.getPermissions(username);
        for (String string : userRoles) 
        {
            userPerms.add(new GrantedAuthorityImpl(string));
        }

        return userPerms;
    }

}

UserRoleServiceImpl.java (IUserRoleService的实施)

package com.company.group.appname.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.company.group.appname.service.IUserRoleService;

@Service("userRoleService")
public class UserRoleServiceImpl implements IUserRoleService {

    private static Logger log = Logger.getLogger(UserRoleServiceImpl.class);

    public List<String> getPermissions(String username) {


        List<String> roles = new ArrayList<String>();
        roles.add("CUSTOMADMIN");
        return roles;
    }

}

这一切都认证很好,但我不知道如何从这里获取Active目录组。我希望能够做的是getPermissions(username)方法,我希望能够从Active Directory获取与用户名相关联的组列表,如果它包含特定组名,则返回其他返回null (或其他一些角色)。

我会诚实地说,我已经看了很多代码示例,通过Active目录进行身份验证,然后可以获取组,但我从来没有让它们工作(我找到的大多数示例都可以解决)有弹簧安全3.1的问题,不幸的是这不是一个选项)我还没有找到一个以这种方式接近它的例子。

任何指导或帮助都会很棒

1 个答案:

答案 0 :(得分:3)

如果您真的无法从3.0升级,为什么不将ActiveDirectoryLdapAuthenticationProvider类从3.1复制到您的代码库中并使用它?它从AD用户条目中的memberOf属性加载用户权限。

从3.0升级到3.1应该是相对轻松的,但如果你不能阻止你使用个别类作为你自己的构建的一部分。那么你就不需要你编写的LdapAuthoritiesPopulator代码(这对于AD来说也不是很合适)。