Spring PasswordEncoder实现

Spring PasswordEncoder Implementation

Introduction

小号pring Security provides multiple PasswordEncoder implementations with BCRYPT as the recommended implementation. However, the use-case of sharing an authentication database with an external application, Dovecot, is examined in this article. Dovecot uses an MD5-CRYPT algorithm.

Complete javadoc is provided.

Reference

The actual encryption algorithm is captured in the Dovecot source file password-scheme-md5crypt.c.

Implementation

The implementation extends DelegatingPasswordEncoder to provide decryption services for the other Spring Security supported password types. Two inner classes, each subclasses of PasswordEncoder, provide MD5-CRYPŤ and PLAIN implementations.

@Service
public class MD5CryptPasswordEncoder extends DelegatingPasswordEncoder {
    ...

    private static final String MD5_CRYPT = "MD5-CRYPT";
    private static final HashMap<String,PasswordEncoder> MAP = new HashMap<>();

    static {
        MAP.put(MD5_CRYPT, MD5Crypt.INSTANCE);
        MAP.put("CLEAR", NoCrypt.INSTANCE);
        MAP.put("CLEARTEXT", NoCrypt.INSTANCE);
        MAP.put("PLAIN", NoCrypt.INSTANCE);
        MAP.put("PLAINTEXT", NoCrypt.INSTANCE);
    }

    ...

    public MD5CryptPasswordEncoder() {
        super(MD5_CRYPT, MAP);

        setDefaultPasswordEncoderForMatches(PasswordEncoderFactories.createDelegatingPasswordEncoder());
    }

    private static class NoCrypt implements PasswordEncoder {
        ...
        public static final NoCrypt INSTANCE = new NoCrypt();
        ...
    }

    private static class MD5Crypt extends NoCrypt {
        ...
        public static final MD5Crypt INSTANCE = new MD5Crypt();
        ...
    }
}

The MD5Crypt inner class implementation is straightforward:

    private static class MD5Crypt extends NoCrypt {
        private static final String MD5 = "md5";
        private static final String MAGIC = "$1$";
        private static final int SALT_LENGTH = 8;

        public static final MD5Crypt INSTANCE = new MD5Crypt();

        public MD5Crypt() { }

        @Override
        public String encode(CharSequence raw) {
            return encode(raw.toString(), salt(SALT_LENGTH));
        }

        private String encode(String raw, String salt) {
            if (salt.length() > SALT_LENGTH) {
                salt = salt.substring(0, SALT_LENGTH);
            }

            return (MAGIC + salt + "$" + encode(raw.getBytes(UTF_8), salt.getBytes(UTF_8)));
        }

        private String encode(byte[] password, byte[] salt) {
            /*
             * See source and password-scheme-md5crypt.c.
             */
        }

        @Override
        public boolean matches(CharSequence raw, String encoded) {
            String salt = null;

            if (encoded.startsWith(MAGIC)) {
                salt = encoded.substring(MAGIC.length()).split("[$]")[0];
            } else {
                throw new IllegalArgumentException("Invalid format");
            }

            return encoded.equals(encode(raw.toString(), salt));
        }
    }

The NoCrypt implementation provides the methods for calculating salt and itoa64 conversion.

Spring Boot Application Integration

The PasswordEncoder may be integrated with the following @Configuration:

package some.application;

import ball.spring.MD5CryptPasswordEncoder;
import ...

@Configuration
public class PasswordEncoderConfiguration {
    ...

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new MD5CryptPasswordEncoder();
    }
}

and must be integrated with a UserDetailsService in a WebSecurityConfigurer:

package some.application;

import ...

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfigurerImpl extends WebSecurityConfigurerAdapter {
    ...

    @Autowired private UserDetailsService userDetailsService;
    @Autowired private PasswordEncoder passwordEncoder;

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder);
    }

    ...
}

from: https://dev.to//allenball/spring-passwordencoder-implementation-3edf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值