/** * */ package com.thinkbiganalytics.security.auth.ldap; /*- * #%L * thinkbig-security-auth-ldap * %% * Copyright (C) 2017 ThinkBig Analytics * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import com.thinkbiganalytics.auth.jaas.LoginConfiguration; import com.thinkbiganalytics.auth.jaas.LoginConfigurationBuilder; import com.thinkbiganalytics.auth.jaas.config.JaasAuthConfig; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.ldap.core.support.LdapContextSource; import org.springframework.security.ldap.DefaultSpringSecurityContextSource; import org.springframework.security.ldap.authentication.BindAuthenticator; import org.springframework.security.ldap.authentication.LdapAuthenticator; import org.springframework.security.ldap.authentication.NullLdapAuthoritiesPopulator; import org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator; import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator; import java.net.URI; /** * LDAP login configuration. */ @Configuration @Profile("auth-ldap") public class LdapAuthConfig { @Value("${security.auth.ldap.login.ui:required}") private String uiLoginFlag; @Value("${security.auth.ldap.login.services:required}") private String servicesLoginFlag; @Bean(name = "servicesLdapLoginConfiguration") public LoginConfiguration servicesLdapLoginConfiguration(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator, LoginConfigurationBuilder builder) { // @formatter:off return builder .loginModule(JaasAuthConfig.JAAS_SERVICES) .moduleClass(LdapLoginModule.class) .controlFlag(this.servicesLoginFlag) .option(LdapLoginModule.AUTHENTICATOR, authenticator) .option(LdapLoginModule.AUTHORITIES_POPULATOR, authoritiesPopulator) .add() .build(); // @formatter:on } @Bean(name = "uiLdapLoginConfiguration") public LoginConfiguration uiLdapLoginConfiguration(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator, LoginConfigurationBuilder builder) { // @formatter:off return builder .loginModule(JaasAuthConfig.JAAS_UI) .moduleClass(LdapLoginModule.class) .controlFlag(this.uiLoginFlag) .option(LdapLoginModule.AUTHENTICATOR, authenticator) .option(LdapLoginModule.AUTHORITIES_POPULATOR, authoritiesPopulator) .add() .build(); // @formatter:on } @Bean @ConfigurationProperties("security.auth.ldap.server") public LdapContextSourceFactory ldapContextSource() { return new LdapContextSourceFactory(); } @Bean @ConfigurationProperties("security.auth.ldap.authenticator") public LdapAuthenticatorFactory ldapAuthenticator(LdapContextSource context) { return new LdapAuthenticatorFactory(context); } @Bean @ConfigurationProperties("security.auth.ldap.user") public LdapAuthoritiesPopulatorFactory ldapAuthoritiesPopulator(LdapContextSource context) { return new LdapAuthoritiesPopulatorFactory(context); } public static class LdapContextSourceFactory extends AbstractFactoryBean<LdapContextSource> { private URI uri; private String authDn; private char[] password = "".toCharArray(); public void setUri(String uri) { this.uri = URI.create(uri); } public void setAuthDn(String userDn) { this.authDn = userDn; } public void setPassword(String password) { this.password = password.toCharArray(); } @Override public Class<?> getObjectType() { return LdapContextSource.class; } @Override protected LdapContextSource createInstance() throws Exception { DefaultSpringSecurityContextSource cxt = new DefaultSpringSecurityContextSource(this.uri.toASCIIString()); if (StringUtils.isNotEmpty(this.authDn)) { cxt.setUserDn(this.authDn); } if (ArrayUtils.isNotEmpty(this.password)) { cxt.setPassword(new String(this.password)); } cxt.setCacheEnvironmentProperties(false); cxt.afterPropertiesSet(); return cxt; } } public static class LdapAuthenticatorFactory extends AbstractFactoryBean<LdapAuthenticator> { private LdapContextSource contextSource; private String[] userDnPatterns; public LdapAuthenticatorFactory(LdapContextSource contextSource) { super(); this.contextSource = contextSource; } public void setUserDnPatterns(String userDnPatterns) { this.userDnPatterns = userDnPatterns.split("\\|"); } @Override public Class<?> getObjectType() { return LdapAuthenticator.class; } @Override protected LdapAuthenticator createInstance() throws Exception { BindAuthenticator auth = new BindAuthenticator(this.contextSource); auth.setUserDnPatterns(userDnPatterns); return auth; } } public static class LdapAuthoritiesPopulatorFactory extends AbstractFactoryBean<LdapAuthoritiesPopulator> { private LdapContextSource contextSource; private String groupsBase; private String groupNameAttr; private boolean enableGroups = false; public LdapAuthoritiesPopulatorFactory(LdapContextSource contextSource) { super(); this.contextSource = contextSource; } public void setGroupsBase(String groupsOu) { this.groupsBase = groupsOu; } public void setGroupNameAttr(String groupRoleAttribute) { this.groupNameAttr = groupRoleAttribute; } public void setEnableGroups(boolean enabled) { this.enableGroups = enabled; } @Override public Class<?> getObjectType() { return LdapAuthoritiesPopulator.class; } @Override protected LdapAuthoritiesPopulator createInstance() throws Exception { if (this.enableGroups) { DefaultLdapAuthoritiesPopulator authPopulator = new DefaultLdapAuthoritiesPopulator(this.contextSource, this.groupsBase); authPopulator.setGroupRoleAttribute(this.groupNameAttr); authPopulator.setRolePrefix(""); authPopulator.setConvertToUpperCase(false); return authPopulator; } else { return new NullLdapAuthoritiesPopulator(); } } } }