Springboot2的Security框架用的是5.0的,較之4.0的密碼加密方式有了很大的改變.spring security 5中主推的加密方式爲BCrypt,因爲這種加密方式效率很低,屬於慢加密,可是加密強度很高,現有的機器性能難以暴力破解,可是隨着科技的進步,機器性能加強,破解這種加密方式也會成爲可能,可是加密方式也會不斷更新.redis
廢話說到這裏,因爲性能要求,對該加密登陸的壓測,只能達到50-80qps,這無疑對高併發登陸是不能接受的,因此咱們須要改掉這種加密方式,咱們選擇了MD5的加密.修改以前的安全配置以下.spring
@EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public UserDetailsService userDetailsService; @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } /** * 全局用戶信息 * * @param auth * 認證管理 * @throws Exception * 用戶認證異常信息 */ @Autowired public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); } /** * 認證管理 * * @return 認證管理對象 * @throws Exception * 認證異常信息 */ @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } /** * http安全配置 * * @param http * http安全對象 * @throws Exception * http安全異常信息 */ @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers(PermitAllUrl.permitAllUrl()).permitAll().anyRequest().authenticated().and() .httpBasic().and().csrf().disable(); } }
修改後,咱們只使用MD5進行加密數據庫
@EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public UserDetailsService userDetailsService; // @Bean // public BCryptPasswordEncoder bCryptPasswordEncoder() { // return new BCryptPasswordEncoder(); // } @Bean PasswordEncoder passwordEncoder(){ String idForEncode = "MD5"; Map encoders = new HashMap<>(); encoders.put(idForEncode, new BCryptPasswordEncoder()); encoders.put("MD5", new MessageDigestPasswordEncoder("MD5")); PasswordEncoder delegatingPasswordEncoder = new DelegatingPasswordEncoder(idForEncode, encoders); return delegatingPasswordEncoder; // return PasswordEncoderFactories.createDelegatingPasswordEncoder(); } /** * 全局用戶信息 * * @param auth * 認證管理 * @throws Exception * 用戶認證異常信息 */ @Autowired public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } /** * 認證管理 * * @return 認證管理對象 * @throws Exception * 認證異常信息 */ @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } /** * http安全配置 * * @param http * http安全對象 * @throws Exception * http安全異常信息 */ @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers(PermitAllUrl.permitAllUrl()).permitAll().anyRequest().authenticated().and() .httpBasic().and().csrf().disable(); } }
這裏須要注意的是,因爲只使用了MD5進行加密,在訪問的時候,假設咱們使用的是superadmin用戶名,密碼123456緩存
http://192.168.5.182:36178/oauth/token?grant_type=password&client_id=system&client_secret=system&scope=app&username=superadmin&password=123456安全
這個client_id=system&client_secret=system在數據庫中是有對應的,以前的對應是用BCrypt加密的,因此在oauth_client_details表中,是這樣的併發
這裏面的client_secret的值實際上是system字符串的BCrypt加密結果,咱們須要改爲以下所示app
這個值一樣也是system,不過是由MD5加密的結果,主要須要加前綴{MD5}.這樣在app_user表中,信息以下框架
密碼是由123456的MD5加密結果.這樣在訪問中,咱們就能夠獲取訪問的結果access_tokenide
{"access_token":"65411be1-b7be-46e5-8d72-c0624da33ed7","token_type":"bearer","refresh_token":"43eb498f-d431-4c96-a5b5-3bc007c9c189","expires_in":25690,"scope":"app"}高併發
但值得注意的是,有時候這樣修改後未必能獲得咱們所須要的結果,那是由於在redis中的緩存問題,因爲前一次在BCrypt的加密下已經有了緩存,因此會報錯,咱們須要手工清除一下Redis中的緩存,這樣就會從新創建MD5加密後的緩存,就不會再出現問題了.通過壓測,結果已經達到了2000左右的qps,已經大大高於50-80了.