介绍
在前面例子中,密码都是明文,这样是不安全的,网上有很多数据库泄露事件,用户数据泄露后,黑客通过用户名、密码明文就能登录
所以要用BCryptPasswordEncoder给密码加密
用户表已存在的密码
如果用户表中已经有一些数据,密码是明文,如下:
id|nickname|password|role |username|
--|--------|--------|-----|--------|
1 |超级管理员 |123456 |admin|admin |
那么通过BCryptPasswordEncoder类,给密码加密后,再保存到数据库中
关于 BCryptPasswordEncoder,详见
https://www.malaoshi.top/show_1EF60lJZZ7h5.html
加密密码
BCryptPasswordEncoder encoder=new BCryptPasswordEncoder();
String pwd=encoder.encode("123456");
System.out.println(pwd);
将结果保存到数据库中
保存到数据库
id|nickname|password |role |username|
--|--------|------------------------------------------------------------|-----|--------|
1 |超级管理员 |$2a$10$0oAVg/n3iP945IxWA0EhjeonmvrbzLlrI2M5wPum77xBC68kVGk8e|admin|admin
修改配置类
关键代码
在配置类中增加下面代码:
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
完整代码
package top.malaoshi.stdsecurity.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import top.malaoshi.stdsecurity.security.SLoginService;
import javax.annotation.Resource;
@Configuration
@EnableWebSecurity
//@EnableGlobalMethodSecurity(securedEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// 指定密码编码器为:BCryptPasswordEncoder
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
// 登录service,自定义实现
@Resource
private SLoginService sLoginService;
// 指定使用自定义的登录service,并指定密码编码器
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(sLoginService).passwordEncoder(passwordEncoder());
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/css/**","/js/**","/img/**");//绕开所有的filter,直接跳过验证
}
// 安全拦截机制
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.authorizeRequests()//url权限配置
// .antMatchers("/index.html").permitAll() // 匹配这些路径可以所有人访问
.antMatchers("/dept/**").hasRole("admin")
.antMatchers("/user/**").hasRole("admin")
.anyRequest().authenticated()
.and()
//login部分
.formLogin()
.loginPage("/login.html")//指定登录页面。所有url前面必须写/,否则报错 'xxx' is not a valid forward URL
// .usernameParameter("user")//登录页面用户名控件name值
// .passwordParameter("pwd")//登录页面密码控件name值
.loginProcessingUrl("/login")//security提供的处理登录url,默认是/login
// .successForwardUrl("/index.html")//登录成功后跳转的页面,需要额外处理才能使用,否则页面会提示错误
.defaultSuccessUrl("/index.html")//登录成功后重定向的页面
.failureUrl("/login_fails.html")//登录失败跳转的页面
// .failureForwardUrl("/login_fails.html")//登录失败不会转发
.permitAll()//让login部分的url可以任意访问
//
// //logout部分
.and()
.logout()//退出登录需要提交post请求
.logoutSuccessUrl("/login.html")//退出成功访问的页面
.invalidateHttpSession(true)//清空session
.permitAll();//让logout部分的url可以任意访问
}
}
注意: 启用了csrf防攻击
测试
登录,
用户名:admin
密码:123456
点击登录,如果不出意外,登录成功!