使用java通过Spring安全性验证LDAP用户

时间:2016-04-16 14:07:06

标签: java spring authentication spring-security spring-ldap

我在Spring安全和Adam Ldap方面遇到了一些麻烦。 Here你可以看到我的帖子没有有用的答案。 我想用我的身份验证java代码来设置spring环境。这是我的java代码:

@Override
public void isAuthenticated(String username, String password) throws LdapException{
    if (databaseMatlabClientServices.getByUsersEnabled(username)== null)
        throw new LdapException("User doesn't exist into DART database. Please contact the administrator!");
    String dn="";;
    //First query to retriev DN
    Hashtable<String, Object> ldapEnv = new Hashtable<String, Object>();
    ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    ldapEnv.put(Context.PROVIDER_URL, env.getRequiredProperty(PROPERTY_NAME_LDAP_URL));
//Without authentication        ldapEnv.put(Context.SECURITY_AUTHENTICATION, "none");
    //With authentication to access to LDAP server
    ldapEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
    ldapEnv.put(Context.SECURITY_PRINCIPAL, env.getRequiredProperty(PROPERTY_NAME_LDAP_NAME));
    ldapEnv.put(Context.SECURITY_CREDENTIALS, env.getRequiredProperty(PROPERTY_NAME_LDAP_PASSWORD));
    String[] returnAttribute = {"dn"};
    DirContext ctx = null;
    NamingEnumeration<SearchResult> results = null;
    try {
        ctx = new InitialDirContext(ldapEnv);
        SearchControls controls = new SearchControls();
        controls.setReturningAttributes(returnAttribute);
        controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// without authentication on local server String filter = "uid=" + username ;
        String filter = "CN=" + username ;
        results = ctx.search(env.getRequiredProperty(PROPERTY_NAME_LDAP_USERSEARCHBASE), filter, controls);
        if (results.hasMore())
            dn = results.nextElement().getNameInNamespace();
        else 
            throw new LdapException("Wrong username. Please retry!");
    } catch (NamingException e) {
        throw new LdapException(e);
    } finally {
        try{
            if (results != null)
                results.close();             
            if (ctx != null) 
                ctx.close();
        }catch(Exception e){
            throw new LdapException(e);
        }
    }

    //Second query to try to access with obtained Dn and given password
    Hashtable<String, Object> authEnv = new Hashtable<String, Object>();
    authEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
    authEnv.put(Context.PROVIDER_URL, env.getRequiredProperty(PROPERTY_NAME_LDAP_URL));
    authEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
    authEnv.put(Context.SECURITY_PRINCIPAL, dn);
    authEnv.put(Context.SECURITY_CREDENTIALS, password);
    DirContext ctx2 = null;
    try {
        ctx2 = new InitialDirContext(authEnv);
    } catch (AuthenticationException authEx) {
        throw new LdapException("Authentication error. Password was wrong");
    } catch(Exception e){
        throw new LdapException(e);
    }finally {
        try{         
            if (ctx2 != null) 
                ctx2.close();
        }catch(Exception e){
            throw new LdapException(e);
        }
    }
}

此代码识别Ldap系统上是否存在用户和密码。 在春天我有

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{
    LdapContextSource contextSource = new LdapContextSource();
    contextSource.setUrl("ldaps://vdap.floal:636/");
    contextSource.setBase("DC=fg,DC=local");
    contextSource.setReferral("follow"); 
    contextSource.setUserDn("CN=A00XXX32,CN=Administration,CN=fdam,DC=fg,DC=local");
    contextSource.setPassword(password);
    contextSource.afterPropertiesSet();
    LdapAuthenticationProviderConfigurer<AuthenticationManagerBuilder>      ldapAuthenticationProviderConfigurer = auth.ldapAuthentication();
    ldapAuthenticationProviderConfigurer
    .contextSource(contextSource)
    .userSearchBase("CN=fdam")
    .userSearchFilter(env.getRequiredProperty("(CN={0})"))
    .ldapAuthoritiesPopulator(myAuthPopulator);     
}

和我的权限populator从数据库

提供角色信息
@Service("myAuthPopulator")
public class MyAuthoritiesPopulator implements LdapAuthoritiesPopulator {

    @Autowired
    private UserServices userServices;
    static final Logger LOG = LoggerFactory.getLogger(MyAuthoritiesPopulator.class);

    @Transactional(readOnly=true)
    @Override
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username) {
        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
        try{
            com.domain.User user = userServices.getByUsersEnabled(username);
            if (user==null){
                LOG.error("Threw exception in MyAuthoritiesPopulator::getGrantedAuthorities : User doesn't exist into DART database" );
            }
            else{
                //Use this if a user can have different roles
//              for(Role role : user.getRole()) {
//                  authorities.add(new SimpleGrantedAuthority(role.getRole()));
//              }
                authorities.add(new SimpleGrantedAuthority(user.getRole().getRole()));
                return authorities;
            }
        }catch(Exception e){
            LOG.error("Threw exception in MyAuthoritiesPopulator::getGrantedAuthorities : " + ErrorExceptionBuilder.buildErrorResponse(e)); }
        return authorities;
    }
}

是否可以合并这两个策略来修复我的问题与Ldap身份验证,所以使用java代码设置Spring?感谢

0 个答案:

没有答案