BCrypt密码加密

一、介绍

BCrypt算法是目前使用比较多的加密、解密算法。SpringSecurity中提供了BCryptPasswordEncoder

优点:
自己写的加密算法或使用MD5,同一密码生成的Hash值一样。而BCrypt算法每次加密生成的Hash值不同。

二、具体使用

1)在SpringSecurity的配置类中,使用@Configuration和@Bean的组合来创建BCryptPasswordEncoder Bean

@EnableWebSecurity
public 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类型

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值