SpringSecurity2

AuthenticationManagerBuilder

在这里插入图片描述
继承了之前提到的AbstractConfiguredSecurityBuilder构造器
在这里插入图片描述
postProcess安全对象的后处理,那么ProviderManager是什么

ProviderManager

Authentication

public interface Authentication extends Principal, Serializable {

	/**
	** 权限
	 */
	Collection<? extends GrantedAuthority> getAuthorities();

	/**
	** 凭证,用户名/密码登陆方式密码就是凭证
	 */
	Object getCredentials();

	/**
	** 存放ip或者证书序列号
	 */
	Object getDetails();

	/**
	 * 要进行身份验证的主体的身份。对于带有用户名和密码的身份验证请求,这将是用户名。调用方应填充身份验证请求的主体
	 */
	Object getPrincipal();

	/**
	* 判断是否被认证
	 */
	boolean isAuthenticated();

	/**
	 * 设置authenticated属性
	 */
	void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;

}

AuthenticationProvider

策略模式典型实现
认证登录不仅仅是账户密码登录,还可能是QQ、微信登录等
之后新增只需要新继承这个Provider即可,符合开闭模式,保证只新增代码,不修改以往代码

public interface AuthenticationProvider {

	/**
	* 使用与 AuthenticationManager.authenticate(Authentication) 相同的协定执行身份验证。
	* 完全经过身份验证的对象,包括凭据。
	 */
	Authentication authenticate(Authentication authentication) throws AuthenticationException;

	/**
	 * 如果这AuthenticationProvider支持指示Authentication的对象,则返回true。
	 */
	boolean supports(Class<?> authentication);

}

AuthenticationManager

public interface AuthenticationManager {

	/**
	 * Attempts to authenticate the passed {@link Authentication} object, returning a
	 * fully populated <code>Authentication</code> object (including granted authorities)
	 * if successful.
	 * <p>
	 * An <code>AuthenticationManager</code> must honour the following contract concerning
	 * exceptions:
	 * <ul>
	 * <li>A {@link DisabledException} must be thrown if an account is disabled and the
	 * <code>AuthenticationManager</code> can test for this state.</li>
	 * <li>A {@link LockedException} must be thrown if an account is locked and the
	 * <code>AuthenticationManager</code> can test for account locking.</li>
	 * <li>A {@link BadCredentialsException} must be thrown if incorrect credentials are
	 * presented. Whilst the above exceptions are optional, an
	 * <code>AuthenticationManager</code> must <B>always</B> test credentials.</li>
	 * </ul>
*尝试对传递 Authentication 的对象进行身份验证,如果成功,则返回完全填充的 Authentication 对象
*必须 AuthenticationManager 履行以下有关例外情况的合同:
* 如果帐户被禁用,AuthenticationManager则必须抛出 ADisabledException,并且可以测试此状态。
* 如果帐户被锁定,AuthenticationManager则必须抛出 ALockedException,并且可以测试帐户锁定。
* 如果提供不正确的凭据,则必须抛出 A BadCredentialsException 。虽然上述例外是可选的, AuthenticationManager 但必须 始终 测试凭据。
	 */
	Authentication authenticate(Authentication authentication) throws AuthenticationException;

}

在这里插入图片描述
关键属性

// 事件发布器
	private AuthenticationEventPublisher eventPublisher = new NullEventPublisher();
// 之前说的策略,用自己授权
	private List<AuthenticationProvider> providers = Collections.emptyList();

	protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
// 父类,使用父类授权
	private AuthenticationManager parent;

	private boolean eraseCredentialsAfterAuthentication = true;
	
@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		Class<? extends Authentication> toTest = authentication.getClass();
		AuthenticationException lastException = null;
		AuthenticationException parentException = null;
		Authentication result = null;
		Authentication parentResult = null;
		int currentPosition = 0;
		int size = this.providers.size();
		// 循环认证
		for (AuthenticationProvider provider : getProviders()) {
			if (!provider.supports(toTest)) {
				continue;
			}
			if (logger.isTraceEnabled()) {
				logger.trace(LogMessage.format("Authenticating request with %s (%d/%d)",
						provider.getClass().getSimpleName(), ++currentPosition, size));
			}
			try {
				result = provider.authenticate(authentication);
				if (result != null) {
					/**
					** 存放ip或者证书序列号
					 */
					// Object getDetails();
					copyDetails(authentication, result);
					break;
				}
			}
			catch (AccountStatusException | InternalAuthenticationServiceException ex) {
				prepareException(ex, authentication);
				throw ex;
			}
			catch (AuthenticationException ex) {
				lastException = ex;
			}
		}
		// 找不到对应的Authentication,则调用父类的授权
		if (result == null && this.parent != null) {
			try {
				parentResult = this.parent.authenticate(authentication);
				result = parentResult;
			}
			catch (ProviderNotFoundException ex) {
			}
			catch (AuthenticationException ex) {
				parentException = ex;
				lastException = ex;
			}
		}
		if (result != null) {
		// 擦除凭证信息
			if (this.eraseCredentialsAfterAuthentication && (result instanceof CredentialsContainer)) {
				((CredentialsContainer) result).eraseCredentials();
			}
			if (parentResult == null) {
				this.eventPublisher.publishAuthenticationSuccess(result);
			}

			return result;
		}

		if (lastException == null) {
			lastException = new ProviderNotFoundException(this.messages.getMessage("ProviderManager.providerNotFound",
					new Object[] { toTest.getName() }, "No AuthenticationProvider found for {0}"));
		}
		if (parentException == null) {
			prepareException(lastException, authentication);
		}
		throw lastException;
	}

相关推荐

  1. SpringSecurity2. 初学SpringSecurity

    2024-04-03 17:58:05       30 阅读
  2. SpringSecurity

    2024-04-03 17:58:05       20 阅读
  3. SpringSecurity源码学习七:OAuth 2.0登录

    2024-04-03 17:58:05       34 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-03 17:58:05       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-03 17:58:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-03 17:58:05       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-03 17:58:05       20 阅读

热门阅读

  1. free函数的用法和注意事项

    2024-04-03 17:58:05       14 阅读
  2. 基于Spring Boot的高校科研信息管理系统

    2024-04-03 17:58:05       16 阅读
  3. C 函数指针与回调函数

    2024-04-03 17:58:05       13 阅读
  4. 深度学习该如何入门?

    2024-04-03 17:58:05       13 阅读
  5. 【MySQL】数据类型2

    2024-04-03 17:58:05       13 阅读
  6. OpenCV轮廓分析

    2024-04-03 17:58:05       16 阅读
  7. 编写HTML文件时的注意事项

    2024-04-03 17:58:05       27 阅读
  8. ES 在浏览器上安装head插件

    2024-04-03 17:58:05       14 阅读
  9. oceanbase-OAT安装

    2024-04-03 17:58:05       17 阅读
  10. ABAP 去除小数掉

    2024-04-03 17:58:05       16 阅读