搬砖民工 Security 第一天

拜读大佬博文

徐靖峰

1. 核心组件

  • SecurityContextHolder
      SecurityContextHolder用于存储安全上下文的信息。
public interface SecurityContext extends Serializable {
	//Authentication 封装了用户认证信息
	Authentication getAuthentication();
	void setAuthentication(Authentication authentication);
}
  • Authentication:
public interface Authentication extends Principal, Serializable {
	//权限信息列表,默认是GrantedAuthority的一些实现类,通常表现形式为代表用户权限信息的一系列字符串
    Collection<? extends GrantedAuthority> getAuthorities();
	//密码信息,用户输入的密码字符串,在认证过后通常会被移除,利于保障安全
    Object getCredentials();
	//细节性信息,记录了访问者的IP地址和sessionid的值。通常实现的接口为WebAuthenticationDetails
    Object getDetails();
	//最重要的用户身份信息,返回UserDetails接口的实现类
    Object getPrincipal();
	//用于告诉AbstractSecurityInterceptor 用户是否已经验证过
    boolean isAuthenticated();
	//设置用户认证状态
    void setAuthenticated(boolean var1) throws IllegalArgumentException;
}
  • WebAuthenticationDetails
public class WebAuthenticationDetails implements Serializable {
    private static final long serialVersionUID = 510L;
    //用户的IP地址
    private final String remoteAddress;
    //用户的sessionId
    private final String sessionId;

    public WebAuthenticationDetails(HttpServletRequest request) {
        this.remoteAddress = request.getRemoteAddr();
        HttpSession session = request.getSession(false);
        this.sessionId = session != null ? session.getId() : null;
    }

    private WebAuthenticationDetails(String remoteAddress, String sessionId) {
        this.remoteAddress = remoteAddress;
        this.sessionId = sessionId;
    }
	... //还有实现的hashCode方法和equals方法
}
  • UserDetails
public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();
    String getPassword();
    String getUsername();
	//用户账户是否过期
    boolean isAccountNonExpired();
	//用户账户是否被锁定
    boolean isAccountNonLocked();
	//用户密码是否过期
    boolean isCredentialsNonExpired();
	//用户是否被启用
    boolean isEnabled();
}
  • AuthenticationManager
      本类是用户认证的核心接口,认证的发起方。
public interface AuthenticationManager {
	//核心的认证方法,由实现类来具体完成验证的逻辑
    Authentication authenticate(Authentication var1) throws AuthenticationException;
}
  • ProviderManager
      ProviderManager是AuthenticationManager的一个主要实现类,在里面维护了一个AuthenticationProvider的列表,存放多种认证方式的provider。默认情况下只要有一个认证方式能够通过那就是认证成功
public Authentication authenticate(Authentication authentication)
			throws AuthenticationException {
		Class<? extends Authentication> toTest = authentication.getClass();
		AuthenticationException lastException = null;
		Authentication result = null;
		Authentication parentResult = null;
		boolean debug = logger.isDebugEnabled();
		//维护的认证Provider 列表
		for (AuthenticationProvider provider : getProviders()) {
			if (!provider.supports(toTest)) {
				continue;
			}
			if (debug) {
				logger.debug("Authentication attempt using "
						+ provider.getClass().getName());
			}
			try {
				//这里去获取验证结果
				result = provider.authenticate(authentication);
				
				if (result != null) {
					copyDetails(authentication, result);
					//只要有一个获得了认证成功,就不再接着认证其它的Provider
					break;
				}
			}
			catch (AccountStatusException e) {
				prepareException(e, authentication);
				throw e;
			}
			catch (InternalAuthenticationServiceException e) {
				prepareException(e, authentication);
				throw e;
			}
			catch (AuthenticationException e) {
				lastException = e;
			}
		}

		if (result == null && parent != null) {
			try {
				//TODO:这个地方有一个父类AuthenticationManager的实例,不知道在这里是什么作用。还有什么情况下parent引用不会为空,
				result = parentResult = parent.authenticate(authentication);
			}
			catch (ProviderNotFoundException e) {
			}
			catch (AuthenticationException e) {
				lastException = e;
			}
		}

		if (result != null) {
			if (eraseCredentialsAfterAuthentication
					&& (result instanceof CredentialsContainer)) {
				((CredentialsContainer) result).eraseCredentials();
			}
			if (parentResult == null) {
				eventPublisher.publishAuthenticationSuccess(result);
			}
			return result;
		}
		if (lastException == null) {
			lastException = new ProviderNotFoundException(messages.getMessage(
					"ProviderManager.providerNotFound",
					new Object[] { toTest.getName() },
					"No AuthenticationProvider found for {0}"));
		}

		prepareException(lastException, authentication);

		throw lastException;
	}
  • UserDetailsService
package org.springframework.security.core.userdetails;
public interface UserDetailsService {
	//这个方法的作用就是提供用户
    UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}

大佬文章第一篇拜读完毕,效仿一下整理自己理解的UML图

Security 核心组件关联关系图

第一篇读完有点感觉了
  1. 用户信息的获取,UserDetailsService[loadUserByUsername(String username)]
  2. 用户信息认证, AuthenticationProvider[authenticate(Authentication authentication)]

趁热打铁 大佬文章第二篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码ge寂寞

谢谢老板,老板大气,老板入大厂

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值