spring security LdapUserServiceBeanDefinitionParser 源码

  • 2022-08-13
  • 浏览 (603)

spring security LdapUserServiceBeanDefinitionParser 代码

文件路径:/config/src/main/java/org/springframework/security/config/ldap/LdapUserServiceBeanDefinitionParser.java

/*
 * Copyright 2002-2016 the original author or authors.
 *
 * 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
 *
 *      https://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.
 */

package org.springframework.security.config.ldap;

import org.w3c.dom.Element;

import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.authentication.AbstractUserDetailsServiceBeanDefinitionParser;
import org.springframework.util.StringUtils;

/**
 * @author Luke Taylor
 * @since 2.0
 */
public class LdapUserServiceBeanDefinitionParser extends AbstractUserDetailsServiceBeanDefinitionParser {

	public static final String ATT_SERVER = "server-ref";

	public static final String ATT_USER_SEARCH_FILTER = "user-search-filter";

	public static final String ATT_USER_SEARCH_BASE = "user-search-base";

	public static final String DEF_USER_SEARCH_BASE = "";

	public static final String ATT_GROUP_SEARCH_FILTER = "group-search-filter";

	public static final String ATT_GROUP_SEARCH_BASE = "group-search-base";

	public static final String ATT_GROUP_ROLE_ATTRIBUTE = "group-role-attribute";

	public static final String DEF_GROUP_SEARCH_FILTER = "(uniqueMember={0})";

	public static final String DEF_GROUP_SEARCH_BASE = "";

	static final String ATT_ROLE_PREFIX = "role-prefix";

	static final String ATT_USER_CLASS = "user-details-class";

	static final String ATT_USER_CONTEXT_MAPPER_REF = "user-context-mapper-ref";

	static final String OPT_PERSON = "person";

	static final String OPT_INETORGPERSON = "inetOrgPerson";

	public static final String LDAP_SEARCH_CLASS = "org.springframework.security.ldap.search.FilterBasedLdapUserSearch";

	public static final String PERSON_MAPPER_CLASS = "org.springframework.security.ldap.userdetails.PersonContextMapper";

	public static final String INET_ORG_PERSON_MAPPER_CLASS = "org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper";

	public static final String LDAP_USER_MAPPER_CLASS = "org.springframework.security.ldap.userdetails.LdapUserDetailsMapper";

	public static final String LDAP_AUTHORITIES_POPULATOR_CLASS = "org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator";

	@Override
	protected String getBeanClassName(Element element) {
		return "org.springframework.security.ldap.userdetails.LdapUserDetailsService";
	}

	@Override
	protected void doParse(Element elt, ParserContext parserContext, BeanDefinitionBuilder builder) {
		if (!StringUtils.hasText(elt.getAttribute(ATT_USER_SEARCH_FILTER))) {
			parserContext.getReaderContext().error("User search filter must be supplied", elt);
		}
		builder.addConstructorArgValue(parseSearchBean(elt, parserContext));
		builder.getRawBeanDefinition().setSource(parserContext.extractSource(elt));
		builder.addConstructorArgValue(parseAuthoritiesPopulator(elt, parserContext));
		builder.addPropertyValue("userDetailsMapper", parseUserDetailsClassOrUserMapperRef(elt, parserContext));
	}

	static RootBeanDefinition parseSearchBean(Element elt, ParserContext parserContext) {
		String userSearchFilter = elt.getAttribute(ATT_USER_SEARCH_FILTER);
		String userSearchBase = elt.getAttribute(ATT_USER_SEARCH_BASE);
		Object source = parserContext.extractSource(elt);
		if (StringUtils.hasText(userSearchBase)) {
			if (!StringUtils.hasText(userSearchFilter)) {
				parserContext.getReaderContext()
						.error(ATT_USER_SEARCH_BASE + " cannot be used without a " + ATT_USER_SEARCH_FILTER, source);
			}
		}
		else {
			userSearchBase = DEF_USER_SEARCH_BASE;
		}
		if (!StringUtils.hasText(userSearchFilter)) {
			return null;
		}
		BeanDefinitionBuilder searchBuilder = BeanDefinitionBuilder.rootBeanDefinition(LDAP_SEARCH_CLASS);
		searchBuilder.getRawBeanDefinition().setSource(source);
		searchBuilder.addConstructorArgValue(userSearchBase);
		searchBuilder.addConstructorArgValue(userSearchFilter);
		searchBuilder.addConstructorArgValue(parseServerReference(elt, parserContext));
		return (RootBeanDefinition) searchBuilder.getBeanDefinition();
	}

	static RuntimeBeanReference parseServerReference(Element elt, ParserContext parserContext) {
		String server = elt.getAttribute(ATT_SERVER);
		boolean requiresDefaultName = false;
		if (!StringUtils.hasText(server)) {
			server = BeanIds.CONTEXT_SOURCE;
			requiresDefaultName = true;
		}
		RuntimeBeanReference contextSource = new RuntimeBeanReference(server);
		contextSource.setSource(parserContext.extractSource(elt));
		registerPostProcessorIfNecessary(parserContext.getRegistry(), requiresDefaultName);
		return contextSource;
	}

	private static void registerPostProcessorIfNecessary(BeanDefinitionRegistry registry, boolean defaultNameRequired) {
		if (registry.containsBeanDefinition(BeanIds.CONTEXT_SOURCE_SETTING_POST_PROCESSOR)) {
			if (defaultNameRequired) {
				BeanDefinition bd = registry.getBeanDefinition(BeanIds.CONTEXT_SOURCE_SETTING_POST_PROCESSOR);
				bd.getPropertyValues().addPropertyValue("defaultNameRequired", defaultNameRequired);
			}
			return;
		}
		BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(ContextSourceSettingPostProcessor.class);
		bdb.addPropertyValue("defaultNameRequired", defaultNameRequired);
		registry.registerBeanDefinition(BeanIds.CONTEXT_SOURCE_SETTING_POST_PROCESSOR, bdb.getBeanDefinition());
	}

	static BeanMetadataElement parseUserDetailsClassOrUserMapperRef(Element elt, ParserContext parserContext) {
		String userDetailsClass = elt.getAttribute(ATT_USER_CLASS);
		String userMapperRef = elt.getAttribute(ATT_USER_CONTEXT_MAPPER_REF);
		if (StringUtils.hasText(userDetailsClass) && StringUtils.hasText(userMapperRef)) {
			parserContext.getReaderContext().error("Attributes " + ATT_USER_CLASS + " and "
					+ ATT_USER_CONTEXT_MAPPER_REF + " cannot be used together.", parserContext.extractSource(elt));
		}
		if (StringUtils.hasText(userMapperRef)) {
			return new RuntimeBeanReference(userMapperRef);
		}
		RootBeanDefinition mapper = getMapper(userDetailsClass);
		mapper.setSource(parserContext.extractSource(elt));
		return mapper;
	}

	private static RootBeanDefinition getMapper(String userDetailsClass) {
		if (OPT_PERSON.equals(userDetailsClass)) {
			return new RootBeanDefinition(PERSON_MAPPER_CLASS, null, null);
		}
		if (OPT_INETORGPERSON.equals(userDetailsClass)) {
			return new RootBeanDefinition(INET_ORG_PERSON_MAPPER_CLASS, null, null);
		}
		return new RootBeanDefinition(LDAP_USER_MAPPER_CLASS, null, null);
	}

	static RootBeanDefinition parseAuthoritiesPopulator(Element elt, ParserContext parserContext) {
		String groupSearchFilter = elt.getAttribute(ATT_GROUP_SEARCH_FILTER);
		String groupSearchBase = elt.getAttribute(ATT_GROUP_SEARCH_BASE);
		String groupRoleAttribute = elt.getAttribute(ATT_GROUP_ROLE_ATTRIBUTE);
		String rolePrefix = elt.getAttribute(ATT_ROLE_PREFIX);
		if (!StringUtils.hasText(groupSearchFilter)) {
			groupSearchFilter = DEF_GROUP_SEARCH_FILTER;
		}
		if (!StringUtils.hasText(groupSearchBase)) {
			groupSearchBase = DEF_GROUP_SEARCH_BASE;
		}
		BeanDefinitionBuilder populator = BeanDefinitionBuilder.rootBeanDefinition(LDAP_AUTHORITIES_POPULATOR_CLASS);
		populator.getRawBeanDefinition().setSource(parserContext.extractSource(elt));
		populator.addConstructorArgValue(parseServerReference(elt, parserContext));
		populator.addConstructorArgValue(groupSearchBase);
		populator.addPropertyValue("groupSearchFilter", groupSearchFilter);
		populator.addPropertyValue("searchSubtree", Boolean.TRUE);
		if (StringUtils.hasText(rolePrefix)) {
			if ("none".equals(rolePrefix)) {
				rolePrefix = "";
			}
			populator.addPropertyValue("rolePrefix", rolePrefix);
		}
		if (StringUtils.hasLength(groupRoleAttribute)) {
			populator.addPropertyValue("groupRoleAttribute", groupRoleAttribute);
		}
		return (RootBeanDefinition) populator.getBeanDefinition();
	}

}

相关信息

spring security 源码目录

相关文章

spring security AbstractLdapAuthenticationManagerFactory 源码

spring security ContextSourceSettingPostProcessor 源码

spring security EmbeddedLdapServerContextSourceFactoryBean 源码

spring security LdapBindAuthenticationManagerFactory 源码

spring security LdapPasswordComparisonAuthenticationManagerFactory 源码

spring security LdapProviderBeanDefinitionParser 源码

spring security LdapServerBeanDefinitionParser 源码

spring security package-info 源码

0  赞