自定义登录的用户名密码
第一种方式:通过配置文件application.properties设置
spring.security.user.name=superadmin
spring.security.user.password=superadmin
第二种方式:通过配置类
新建配置类SecurityConfig继承WebSecurityConfigurerAdapter重写configure(AuthenticationManagerBuilder auth)方法在里面进行账户密码角色的设置
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String password = bCryptPasswordEncoder.encode("123456");
auth.inMemoryAuthentication().withUser("superadmin").password(password).roles("admin");
}
@Bean
PasswordEncoder password(){
return new BCryptPasswordEncoder();
}
}
另外要提的一点是WebSecurityConfigurerAdapter类在5.7版本被@Deprecated所标记了
第三种方式:自定义编写实现类,实现UserDetailsService接口,将用户认证提取到业务层进一步实现个性化
第一步 创建配置类,设置使用哪个userDetailsService实现类
@Configuration
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(password());
}
@Bean
PasswordEncoder password(){
return new BCryptPasswordEncoder();
}
}
第二步 编写实现类,返回User对象,User对象有用户名密码和操作权限
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
return new User("admin",new BCryptPasswordEncoder().encode("123456"),auths);
}
}
运行登录验证没问题
查询数据库完成认证
进一步抽离,将用户信息存储到数据库中,更符合实际应用,例子使用了mybatis-plus
第一步 准备库表,基础类
CREATE TABLE users (
id int NOT NULL,
username varchar(45) DEFAULT NULL,
password varchar(45) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into security_demo.users values(1,'admin','123456');
@Data
@TableName("users")
public class UsersEntity {
private Integer id;
private String username;
private String password;
}
@Repository
public interface UsersMapper extends BaseMapper<UsersEntity> {
}
第二步 实现登录验证
在loadUserByUsername方法中编写登录验证过程
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UsersMapper usersMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
QueryWrapper<UsersEntity> wrapper = new QueryWrapper<>();
wrapper.eq("username",username);
wrapper.last(" limit 1");
UsersEntity user = usersMapper.selectOne(wrapper);
if(user ==null || user.getId() == null){
throw new UsernameNotFoundException("用户名或密码错误");
}
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
return new User("admin",new BCryptPasswordEncoder().encode("123456"),auths);
}
}
验证,使用数据库中的数据可以登录
自定义登录页面
在配置类SecurityConfigTest重写protected void configure(HttpSecurity http)方法实现相关配置
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
//登录页面设置
.loginPage("/login.html")
//登录访问路径
.loginProcessingUrl("/user/login")
//登录成功后跳转的页面
.defaultSuccessUrl("/test/index").permitAll()
//设置白名单
.and().authorizeRequests()
.antMatchers("/test/hello","/user/login").permitAll()
//关闭ssrf防护
.anyRequest().authenticated()
.and().csrf().disable();
}
编写配置类中相关页面与接口
在resources.static文件夹中创建login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/user/login" method="post">
用户名:<input type="text" name="username">
<br/>
密 码:<input type="text" name="password">
<br/>
<input type="submit" value="login">
</form>
</body>
</html>
TestController中添加index方法
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
@GetMapping("/index")
public String index(){
return "index";
}
}
运行跳转页面,登录功能正常