Spring Security 接口详解 (三)

目录

一、概述

二、UserDetailsService详解

三、PasswordEncoder 密码解析器详解


Spring Security 学习专栏

1. Spring Security 入门学习(一)

2. Spring Security 自定义认证管理器和讲解 (二)

3. Spring Security 接口详解 (三)

4. Spring Security 工作原理 (四)

 

一、概述

通过前面几篇文章大概了解和学习Spring Security,看原理相关文章确实比较枯燥(也可以先学习后面的章节,在学习这篇文章),但是对学习Spring Security会了解更加透彻。

二、UserDetailsService详解

当什么也没有配置的时候,账号和密码是由 Spring Security 定义生成的。而在实际项目中账号和密码都是从数据库中查询出来的。所以我们要通过自定义逻辑控制认证逻辑。如果需要自定义逻辑时,只需要实现 UserDetailsService 接口即可。接口定义如下:

public interface UserDetailsService {

	/**
	 * Locates the user based on the username. In the actual implementation, the search
	 * may possibly be case sensitive, or case insensitive depending on how the
	 * implementation instance is configured. In this case, the UserDetails
	 * object that comes back may have a username that is of a different case than what
	 * was actually requested..
	 *
	 * @param username the username identifying the user whose data is required.
	 *
	 * @return a fully populated user record (never null)
	 *
	 * @throws UsernameNotFoundException if the user could not be found or the user has no
	 * GrantedAuthority
	 */
	UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}


返回值 UserDetails 是一个接口,定义如下

public interface UserDetails extends Serializable {


	/**
	 *  获取所有权限
	 *
	 */
	Collection getAuthorities();

	/**
	 * 密码
	 *
	 */
	String getPassword();

	/**
	 * 用户名
	 *
	 */
	String getUsername();

	/**
	 * 账号是否过期
	 *
	 */
	boolean isAccountNonExpired();

	/**
	 * 账号是否被锁
	 *
	 */
	boolean isAccountNonLocked();

	/**
	 * 凭证(密码) 是否过期
	 */
	boolean isCredentialsNonExpired();

	/**
	 * 是否可用
	 */
	boolean isEnabled();
}

的实例就只能返回接口的实现类。SpringSecurity 中提供了如下的实例。对于我们只需要使用里面的  User 类即可。注意 User 的全限定路径是:
org.springframework.security.core.userdetails.User 此处经常和系统中自己开发的 User 类弄混。

 Spring Security 接口详解 (三)_第1张图片

其中构造方法有两个,调用其中任何一个都可以实例化
UserDetails 实现类  User 类的实例。而三个参数的构造方法实际上也是调用 7 个参数的构造方法。

/**
	 * Calls the more complex constructor with all boolean arguments set to {@code true}.
	 */
	public User(String username, String password,
			Collection authorities) {
		this(username, password, true, true, true, true, authorities);
	}

 此处的用户名应该是客户端传递过来的用户名。而密码应该是从数据库中查询出来的密码。SpringSecurity 会根据 User 中的  password 和客户端传递过来的  password 进行比较。如果相同则表示认证通过,如果不相同表示认证失败。

 UserDetails 里面的权限对于后面学习授权是很有必要的,包含的所有内容为此用户具有的权限,如有里面没有包含某个权限,而在做某个事情时必须包含某个权限则会出现 403。通常都是通过AuthorityUtils.commaSeparatedStringToAuthorityList(“”) 来创建 authorities 集合对象的。参数是一个字符串,多个权限使用逗号分隔。


方法参数
方法参数表示用户名。此值是客户端表单传递过来的数据。默认情况下必须叫  username ,否则无法接收。


异常
UsernameNotFoundException 用户名没有发现异常。在 loadUserByUsername 中是需要通过自己的
逻辑从数据库中取值的。如果通过用户名没有查询到对应的数据,应该抛出UsernameNotFoundException ,系统就知道用户名没有查询到。

 

三、PasswordEncoder 密码解析器详解

Spring Security 要求容器中必须有 PasswordEncoder 实例。所以当自定义登录逻辑时要求必须给容器注入 PaswordEncoder 的bean对象。


接口介绍

  • encode() :把参数按照特定的解析规则进行解析。
  • matches() :验证从存储中获取的编码密码与编码后提交的原始密码是否匹配。如果密码匹配,则返回 true;如果不匹配,则返回 false。第一个参数表示需要被解析的密码。第二个参数表示存储的密码。
  • upgradeEncoding() :如果解析的密码能够再次进行解析且达到更安全的结果则返回 true,否则返回 false。默认返回 false。
public interface PasswordEncoder {

	String encode(CharSequence rawPassword);


	boolean matches(CharSequence rawPassword, String encodedPassword);


	default boolean upgradeEncoding(String encodedPassword) {
		return false;
	}

内置解析器介绍
在 Spring Security 中内置了很多解析器。

Spring Security 接口详解 (三)_第2张图片

 BCryptPasswordEncoder 简介

BCryptPasswordEncoder 是 Spring Security 官方推荐的密码解析器,平时多使用这个解析器。

BCryptPasswordEncoder 是对  bcrypt 强散列方法的具体实现。是基于Hash算法实现的单向加密。
可以通过strength控制加密强度,默认 10.


@Slf4j(topic = "BCryptPasswordTest")
public class BCryptPasswordTest {

    public static void main(String[] args) {
        //创建解析器
        PasswordEncoder pw = new BCryptPasswordEncoder();
        //对密码加密
        String encode = pw.encode("123");
        log.info("encode:{}",encode);
        //判断原字符和加密后内容是否匹配
        boolean matches = pw.matches("1234", encode);
        log.info("=====>matches:{}", matches);

    }

}

 

你可能感兴趣的:(Spring,Spring,Security,PasswordEncoder)