spring security AbstractLdapAuthenticationProvider 源码

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

spring security AbstractLdapAuthenticationProvider 代码

文件路径:/ldap/src/main/java/org/springframework/security/ldap/authentication/AbstractLdapAuthenticationProvider.java

/*
 * Copyright 2002-2022 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.ldap.authentication;

import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.ldap.userdetails.LdapUserDetailsMapper;
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * Base class for the standard {@code LdapAuthenticationProvider} and the
 * {@code ActiveDirectoryLdapAuthenticationProvider}.
 *
 * @author Luke Taylor
 * @since 3.1
 */
public abstract class AbstractLdapAuthenticationProvider implements AuthenticationProvider, MessageSourceAware {

	protected final Log logger = LogFactory.getLog(getClass());

	protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();

	private boolean useAuthenticationRequestCredentials = true;

	private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();

	protected UserDetailsContextMapper userDetailsContextMapper = new LdapUserDetailsMapper();

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication,
				() -> this.messages.getMessage("LdapAuthenticationProvider.onlySupports",
						"Only UsernamePasswordAuthenticationToken is supported"));
		UsernamePasswordAuthenticationToken userToken = (UsernamePasswordAuthenticationToken) authentication;
		String username = userToken.getName();
		String password = (String) authentication.getCredentials();
		if (!StringUtils.hasLength(username)) {
			throw new BadCredentialsException(
					this.messages.getMessage("LdapAuthenticationProvider.emptyUsername", "Empty Username"));
		}
		if (!StringUtils.hasLength(password)) {
			throw new BadCredentialsException(
					this.messages.getMessage("AbstractLdapAuthenticationProvider.emptyPassword", "Empty Password"));
		}
		Assert.notNull(password, "Null password was supplied in authentication token");
		DirContextOperations userData = doAuthentication(userToken);
		UserDetails user = this.userDetailsContextMapper.mapUserFromContext(userData, authentication.getName(),
				loadUserAuthorities(userData, authentication.getName(), (String) authentication.getCredentials()));
		return createSuccessfulAuthentication(userToken, user);
	}

	protected abstract DirContextOperations doAuthentication(UsernamePasswordAuthenticationToken auth);

	protected abstract Collection<? extends GrantedAuthority> loadUserAuthorities(DirContextOperations userData,
			String username, String password);

	/**
	 * Creates the final {@code Authentication} object which will be returned from the
	 * {@code authenticate} method.
	 * @param authentication the original authentication request token
	 * @param user the <tt>UserDetails</tt> instance returned by the configured
	 * <tt>UserDetailsContextMapper</tt>.
	 * @return the Authentication object for the fully authenticated user.
	 */
	protected Authentication createSuccessfulAuthentication(UsernamePasswordAuthenticationToken authentication,
			UserDetails user) {
		Object password = this.useAuthenticationRequestCredentials ? authentication.getCredentials()
				: user.getPassword();
		UsernamePasswordAuthenticationToken result = UsernamePasswordAuthenticationToken.authenticated(user, password,
				this.authoritiesMapper.mapAuthorities(user.getAuthorities()));
		result.setDetails(authentication.getDetails());
		this.logger.debug("Authenticated user");
		return result;
	}

	@Override
	public boolean supports(Class<?> authentication) {
		return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
	}

	/**
	 * Determines whether the supplied password will be used as the credentials in the
	 * successful authentication token. If set to false, then the password will be
	 * obtained from the UserDetails object created by the configured
	 * {@code UserDetailsContextMapper}. Often it will not be possible to read the
	 * password from the directory, so defaults to true.
	 * @param useAuthenticationRequestCredentials
	 */
	public void setUseAuthenticationRequestCredentials(boolean useAuthenticationRequestCredentials) {
		this.useAuthenticationRequestCredentials = useAuthenticationRequestCredentials;
	}

	@Override
	public void setMessageSource(MessageSource messageSource) {
		this.messages = new MessageSourceAccessor(messageSource);
	}

	/**
	 * Sets the {@link GrantedAuthoritiesMapper} used for converting the authorities
	 * loaded from storage to a new set of authorities which will be associated to the
	 * {@link UsernamePasswordAuthenticationToken}. If not set, defaults to a
	 * {@link NullAuthoritiesMapper}.
	 * @param authoritiesMapper the {@link GrantedAuthoritiesMapper} used for mapping the
	 * user's authorities
	 */
	public void setAuthoritiesMapper(GrantedAuthoritiesMapper authoritiesMapper) {
		this.authoritiesMapper = authoritiesMapper;
	}

	/**
	 * Allows a custom strategy to be used for creating the <tt>UserDetails</tt> which
	 * will be stored as the principal in the <tt>Authentication</tt> returned by the
	 * {@link #createSuccessfulAuthentication(org.springframework.security.authentication.UsernamePasswordAuthenticationToken, org.springframework.security.core.userdetails.UserDetails)}
	 * method.
	 * @param userDetailsContextMapper the strategy instance. If not set, defaults to a
	 * simple <tt>LdapUserDetailsMapper</tt>.
	 */
	public void setUserDetailsContextMapper(UserDetailsContextMapper userDetailsContextMapper) {
		Assert.notNull(userDetailsContextMapper, "UserDetailsContextMapper must not be null");
		this.userDetailsContextMapper = userDetailsContextMapper;
	}

	/**
	 * Provides access to the injected {@code UserDetailsContextMapper} strategy for use
	 * by subclasses.
	 */
	protected UserDetailsContextMapper getUserDetailsContextMapper() {
		return this.userDetailsContextMapper;
	}

}

相关信息

spring security 源码目录

相关文章

spring security AbstractLdapAuthenticator 源码

spring security BindAuthenticator 源码

spring security LdapAuthenticationProvider 源码

spring security LdapAuthenticator 源码

spring security LdapEncoder 源码

spring security NullLdapAuthoritiesPopulator 源码

spring security PasswordComparisonAuthenticator 源码

spring security SpringSecurityAuthenticationSource 源码

spring security UserDetailsServiceLdapAuthoritiesPopulator 源码

spring security package-info 源码

0  赞