SPRING与设计模式----适配器与外观模式

SPRING与设计模式----适配器与外观模式

适配器模式将一个类的接口,转换成客户期望的另一个接口。适配器让原来接口不兼容的类可以合作无间。适配器充满良好的OO设计原则:使用对象组合,以修改接口包装被适配者。实际应用场景:旧系统改造,适应新系统的接口。

外观facade模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。实际应用场景:新旧系统兼容改造,对访问者简化接口的调用。

实际案例:springsecurity4的PasswordEncoder接口的变动,为了兼容原有代码,DaoAuthenticationProvider生成匿名内部来进行新旧接口的适配。

背景:

authentication.encoding.PasswordEncoder,为了避免撞库破解密码,使用了salt来进行密码混淆;

crypto.password.PasswordEncoder 新的接口不再需要salt,就可以保证每次加密后的内容是不一致的,避免了撞库破解。默认推荐的实现类BCryptPasswordEncoder

UML类图:


PasswordEncoder适配器实现代码 ,见DaoAuthenticationProvider源码:

	/**
	 * Sets the PasswordEncoder instance to be used to encode and validate passwords. If
	 * not set, the password will be compared as plain text.
	 * <p>
	 * For systems which are already using salted password which are encoded with a
	 * previous release, the encoder should be of type
	 * {@code org.springframework.security.authentication.encoding.PasswordEncoder}.
	 * Otherwise, the recommended approach is to use
	 * {@code org.springframework.security.crypto.password.PasswordEncoder}.
	 *
	 * @param passwordEncoder must be an instance of one of the {@code PasswordEncoder}
	 * types.
	 */
	public void setPasswordEncoder(Object passwordEncoder) {
		Assert.notNull(passwordEncoder, "passwordEncoder cannot be null");

		if (passwordEncoder instanceof PasswordEncoder) {
			setPasswordEncoder((PasswordEncoder) passwordEncoder);
			return;
		}

		if (passwordEncoder instanceof org.springframework.security.crypto.password.PasswordEncoder) {
			final org.springframework.security.crypto.password.PasswordEncoder delegate = (org.springframework.security.crypto.password.PasswordEncoder) passwordEncoder;
			setPasswordEncoder(new PasswordEncoder() {
				public String encodePassword(String rawPass, Object salt) {
					checkSalt(salt);
					return delegate.encode(rawPass);
				}

				public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
					checkSalt(salt);
					return delegate.matches(rawPass, encPass);
				}

				private void checkSalt(Object salt) {
					Assert.isNull(salt,
							"Salt value must be null when used with crypto module PasswordEncoder");
				}
			});

			return;
		}

		throw new IllegalArgumentException(
				"passwordEncoder must be a PasswordEncoder instance");
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值