本文共 10435 字,大约阅读时间需要 34 分钟。
BCrypt算法是目前使用比较多的加密、解密算法。SpringSecurity中提供了BCryptPasswordEncoder类
优点:
自己写的加密算法或使用MD5,同一密码生成的Hash值一样。而BCrypt算法每次加密生成的Hash值不同。1)在SpringSecurity的配置类中,使用@Configuration和@Bean的组合来创建BCryptPasswordEncoder Bean
@EnableWebSecuritypublic class MySecurityConfig extends WebSecurityConfigurerAdapter { Logger logger = LoggerFactory.getLogger(getClass()); @Autowired MyUserDetailService myUserDetailService; //Control+O 打开重写方法 //定制请求的授权规则 @Override protected void configure(HttpSecurity http) throws Exception { System.out.println("进入到 MySecurityConfig的configure 方法中"); //super.configure(http); /*Spring Security 的默认构造器: 通过调用authorizeRequests()和 anyRequest().authenticated()就会要求所有进入应用的HTTP请求都要进行认证 http .authorizeRequests() .anyRequest().authenticated() .and() .formLogin().and() .httpBasic(); //弹出一个输入用户名、密码的登录框 “/shop/hello” 和 “/shop/order” 这两个路径必须进过认证,并且 “/shop/order” 必须是 post 请求的方式. 对于其他的请求,我们都是 .anyRequest().permitAll() ;都放行. http.authorizeRequests() .antMatchers("/shop/hello").authenticated() .antMatchers(HttpMethod.POST,"/shop/order").authenticated() .anyRequest().permitAll(); antMatchers()方法所使用的路径可能会包括Ant风格的通配符,而regexMatchers()方法则能够接受正则表达式来定义请求路径。 */ // 基于token,所以不需要session http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // /**代表所有的请求 http.authorizeRequests()//方法表示开启了认证规则配置;定义哪些url需要保护,哪些url不需要保护; .antMatchers("/api/**").permitAll()//定义不需要认证就可以访问// .antMatchers("/session/**").permitAll()//定义不需要认证就可以访问// .antMatchers("/component/**").hasAuthority("ROLE_ADMIN") .antMatchers("/home/**").hasAnyAuthority("ROLE_DEV_APPLICATION","ROLE_ADMIN","ROLE_DEV_TERMINAL_IOS") .anyRequest().authenticated();其他的路径都是登录后即可访问// .and().formLogin().loginPage("/")//// //在successHandler中,使用response返回登录成功的json即可,切记不可以使用defaultSuccessUrl,defaultSuccessUrl是只登录成功后重定向的页面,failureHandler也是由于相同的原因不使用failureUrl。// .loginProcessingUrl("/login").successHandler(// new AuthenticationSuccessHandler(){// @Override// public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {// System.out.println(authentication.getDetails());// httpServletResponse.setContentType("application/json;charset=utf-8");// PrintWriter out = httpServletResponse.getWriter();// out.write("{\"status\":\"success\",\"msg\":\"登录成功\"}");// out.flush();// out.close();// }// }).failureHandler(// new AuthenticationFailureHandler() {// @Override// public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {// httpServletResponse.setContentType("application/json;charset=utf-8");// PrintWriter out = httpServletResponse.getWriter();// out.write("{\"status\":\"failed\",\"msg\":\"登录失败\"}");// out.flush();// out.close();// }// }); //http.logout()开启自动配置的注销功能 //1) 访问/logout 表示用户注销,清空session //2) 注销成功会返回/login?logout 页面 //3) logoutSuccessfulUrl 改变2)的设置 http.logout().logoutSuccessUrl("/login"); http.sessionManagement().invalidSessionUrl("/login"); http.rememberMe().rememberMeParameter("remember");// .usernameParameter("username").passwordParameter("password").defaultSuccessUrl("/");定义当需要用户登录时候,转到的登录页面// http.headers().frameOptions().disable();// .antMatchers("/level2/**").hasRole("VIP2")// .antMatchers("/level3/**").hasRole("VIP3"); //开启自动配置的登录功能。如果没有登录,没有权限就会来到登录页面 //1:/login来到登录页 //2:重定向/login?error表示登录失败 //3:更多详细规定 //http.formLogin().defaultSuccessUrl("/user/login.html"); /* iframe */ http.headers().frameOptions().sameOrigin(); // 运行同一个域名中的任何请求 http.csrf().disable(); // 默认是启用的,需要禁用CSRF保护(当不使用cookie时可以禁用csrf) http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class); // 禁用缓存 http.headers().cacheControl(); } //定制请求的认证规则 @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { System.out.println("进入到 configureGlobal 方法中"); System.out.println("auth.userDetailsService(myUserDetailService):" + auth.userDetailsService(myUserDetailService)); //1)获取内存中的用户名和密码// auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) .withUser("1").password(new BCryptPasswordEncoder().encode("1")).roles("USER");// .withUser("1").password(new BCryptPasswordEncoder().encode("1")).authorities("ROLE_TEST");// auth.authenticationProvider(authenticationProvider());// auth.userDetailsService(myUserDetailService).passwordEncoder(passwordEncoder()); //2)获取数据库中的用户名和密码 auth.userDetailsService(myUserDetailService).passwordEncoder(new PasswordEncoder() { @Override public String encode(CharSequence charSequence) { return charSequence.toString(); } @Override public boolean matches(CharSequence charSequence, String s) { return s.equals(charSequence.toString()); } }); } /* 通过AuthenticationProvider方式获取 */ @Bean public DaoAuthenticationProvider authenticationProvider() { System.out.println("进入到 authenticationProvider 方法中"); DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); authProvider.setUserDetailsService(myUserDetailService); authProvider.setPasswordEncoder(passwordEncoder()); return authProvider; } /** * 密码生成策略 * @return */ @Bean public BCryptPasswordEncoder passwordEncoder() { System.out.println("进入到 passwordEncoder 方法中"); return new BCryptPasswordEncoder(); } @Bean public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception { System.out.println("进入到 authenticationTokenFilterBean 方法中"); return new JwtAuthenticationTokenFilter(); }}
2)添加新成员信息时使用encode()进行密码加密
@RestController@RequestMapping(value = "api/umeapiplus/user")public class UserController { private static final Gson gson = new Gson(); @Autowired public UserService userService; @Autowired public BCryptPasswordEncoder bCryptPasswordEncoder; @Autowired public RoleAndUserService roleAndUserService; @Autowired public RoleService roleService; @Autowired CorporationAndUserService corporationAndUserService; @RequestMapping(value = "/updateMemberInfos", method = RequestMethod.POST) public boolean updateMemberInfos(@RequestBody JSONObject jsonObject){ User userOfWeb = gson.fromJson(JSONObject.toJSONString(jsonObject.getJSONObject("user")), User.class); String permission = jsonObject.getString("permission"); String encodedPassword = bCryptPasswordEncoder.encode(userOfWeb.getPassword()); userOfWeb.setPassword(encodedPassword); userOfWeb.setLastLoginDate(new Date());//?? boolean userResult = userService.update(userOfWeb); // 更新权限信息 RoleAndUser roleAndUser = roleAndUserService.findByUserId(userOfWeb.getId()); Integer roleId = roleService.findByRoleName(permission); roleAndUser.setRoleId(roleId); boolean roleAndUserResult = roleAndUserService.update(roleAndUser); return userResult && roleAndUserResult; } @RequestMapping(value = "/addNewMember", method = RequestMethod.POST) public boolean addNewMember(@RequestBody JSONObject jsonObject){ User userOfWeb = gson.fromJson(JSONObject.toJSONString(jsonObject.getJSONObject("user")), User.class); String permission = jsonObject.getString("permission"); Integer corporationId = jsonObject.getInteger("corporationId"); String encodedPassword = bCryptPasswordEncoder.encode(userOfWeb.getPassword()); userOfWeb.setPassword(encodedPassword); userOfWeb.setCreateDate(new Date()); userOfWeb.setLastLoginDate(new Date()); boolean userResult = userService.insertOfReturnId(userOfWeb); //插入tb_role_and_user_new一条新记录 RoleAndUser roleAndUser = new RoleAndUser(); roleAndUser.setUserId(userOfWeb.getId()); Integer roleId = roleService.findByRoleName(permission); roleAndUser.setRoleId(roleId); boolean roleAndUserResult = roleAndUserService.insert(roleAndUser); //插入tb_corporation_and_user一条新记录 CorporationAndUser corporationAndUser = new CorporationAndUser(); corporationAndUser.setUserId(userOfWeb.getId()); corporationAndUser.setCorporationId(corporationId); corporationAndUser.setRoleId(roleId); boolean corporationAndUserResult = corporationAndUserService.insert(corporationAndUser); return userResult && roleAndUserResult && corporationAndUserResult; } @RequestMapping(value = "/deleteMember", method = RequestMethod.GET) public boolean deleteMember(@RequestParam(value = "userId") Integer userId, @RequestParam(value = "corporationId") Integer corporationId){ boolean userResult = userService.deleteByPrimaryKey(userId); boolean roleAndUserResult = roleAndUserService.deleteByUserId(userId); boolean corporationAndUserResult = corporationAndUserService.deleteByUserId(userId); return userResult && roleAndUserResult && corporationAndUserResult; }}
3)解密
使用bCryptPasswordEncoder.matches(原密码,加密后的密码),返回值时boolean类型转载地址:http://wrtii.baihongyu.com/