spring-Security《一》

源码介绍:
public interface UserDetailsService {
    UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}

 里面返回一个UserDetails,来看下UserDetails里面是什么

public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();

    String getPassword();  密码

    String getUsername(); 用户名

    boolean isAccountNonExpired(); 账号是否被过期

    boolean isAccountNonLocked();账号是否被锁定

    boolean isCredentialsNonExpired(); 证书(密码)是否过期

    boolean isEnabled();账号是否被启用
}

 UserDetails也是个接口,那么他肯定有实现类

里面果然有个User去实现它

 

 看下User是什么东东

 

 属性是与接口对应,有两个构造函数

用户名,密码,授权
    public User(String username, String password, Collection<? extends GrantedAuthority> authorities) {
        this(username, password, true, true, true, true, authorities);
    }

就是那一堆属性构造方法了
    public User(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
        if (username != null && !"".equals(username) && password != null) {
            this.username = username;
            this.password = password;
            this.enabled = enabled;
            this.accountNonExpired = accountNonExpired;
            this.credentialsNonExpired = credentialsNonExpired;
            this.accountNonLocked = accountNonLocked;
            this.authorities = Collections.unmodifiableSet(sortAuthorities(authorities));
        } else {
            throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
        }
    }

 

上面介绍了下账户授权,密码呀入口,别着急一丢丢来,慢慢爬
那么问题来了,既然是安全框架,密码不可能是明文吧,那么是怎么加密的呢
于是我们蒙蔽的找啊找,嘿哦看到一个密码Password名称的类

 

 

哎呦我操,你看看还真有,什么抽象的,策略的,加密的我都看不懂,就后面那俩Password的还认识下,点进去看看,上源码

public interface PasswordEncoder {

	/**
	 * Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or
	 * greater hash combined with an 8-byte or greater randomly generated salt.
         人话就是推荐SHA-1或者8位的hash加盐的密码
	 */
	String encode(CharSequence rawPassword);

	/**
	 * Verify the encoded password obtained from storage matches the submitted raw
	 * password after it too is encoded. Returns true if the passwords match, false if
	 * they do not. The stored password itself is never decoded.
	 *
	 * @param rawPassword the raw password to encode and match
	 * @param encodedPassword the encoded password from storage to compare with
	 * @return true if the raw password, after encoding, matches the encoded password from
	 * storage
人话就是原密码与加密的匹配
	 */
	boolean matches(CharSequence rawPassword, String encodedPassword);

	/**
	 * Returns true if the encoded password should be encoded again for better security,
	 * else false. The default implementation always returns false.
	 * @param encodedPassword the encoded password to check
	 * @return true if the encoded password should be encoded again for better security,
	 * else false.
人话就是对加密的密码再次编码
	 */
	default boolean upgradeEncoding(String encodedPassword) {
		return false;
	}
}

 看一下他的实现类,真他妈离谱他妈给离谱开门了,离谱到家了,怎么那么多,老子看哪个,问问用过的老司机吧

 点击去kankan

	public String encode(CharSequence rawPassword) {
		return digest(rawPassword, saltGenerator.generateKey());
	}

好家伙按位运算加盐加特殊字符¥拼接了,
	private String digest(CharSequence rawPassword, byte[] salt) {
		byte[] derived = SCrypt.generate(Utf8.encode(rawPassword), salt, cpuCost, memoryCost, parallelization, keyLength);

		String params = Long
				.toString(((int) (Math.log(cpuCost) / Math.log(2)) << 16L) | memoryCost << 8 | parallelization, 16);

		StringBuilder sb = new StringBuilder((salt.length + derived.length) * 2);
		sb.append("$").append(params).append('$');

		sb.append(encodePart(salt)).append('$');
          
		sb.append(encodePart(derived));

		return sb.toString();
	}

     
       //熟悉的呻吟bsae64编码
	private byte[] decodePart(String part) {
		return Base64.getDecoder().decode(Utf8.encode(part));
	}

	private String encodePart(byte[] part) {
		return Utf8.decode(Base64.getEncoder().encode(part));
	}

 

测试一下:

 

 

随机盐saltGenerator.generateKey()这里已经生成了,就算密码一样,盐不一样结果也不一样

	public String encode(CharSequence rawPassword) {
		return digest(rawPassword, saltGenerator.generateKey());
	}

 

posted @ 2022-05-07 21:52  余生请多指教ANT  阅读(58)  评论(0编辑  收藏  举报