1.spring security搭建
主旨:循序渐进的写代码,从简单到难一步步拆解,每段的代码也会附上,期间会不断的更改,直到呈现出最好的效果,依赖如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.winner</groupId>
<artifactId>security-learn</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>security-learn</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
编写自己的适配器
@EnableWebSecurity
// 注意一定要继承这个类否则项目无法启动
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 自定义配置
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// http.formLogin() 基于表单登录
http.httpBasic()
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
看一下httpBasic的效果,现在请求这个接口
@RestController
public class Order {
@GetMapping("order")
public String order() {
return "order";
}
}
用户名是user,密码看控制台打印的日志,输入用户名密码后就可以请求到资源
换成formLogin的效果
@EnableWebSecurity
// 注意一定要继承这个类否则项目无法启动
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 自定义配置
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
// http.httpBasic()
.and()
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
springSecurity基本原理
实现自己的登录校验逻辑,文章后续会使用数据库实现这段
@Component
public class MyUserDetailsServer implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 实际项目中这些内容需要从数据库表中查询到
return new User(username,"123456", AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}
现在启动项目来看下结果:
请求order接口输入密码后报错了,于是找了一下对应文章发现是spring security5.0以后的版本,密码的一般格式为:{ID} encodedPassword,主要参考了这篇文章https://blog.csdn.net/Hello_World_QWP/article/details/81811462
在SecurityConfig里面添加这行代码
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
这里需要把密码解密passwordEncoder.encode(“123456”)
@Component
public class MyUserDetailsServer implements UserDetailsService {
@Autowired
PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 实际项目中这些内容需要从数据库表中查询到
return new User(username,passwordEncoder.encode("123456") ,
true, true, true, true,
AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}
再次启动项目访问order接口,输入账号密码就可以正常请求了
UserDetail接口字段说明
public interface UserDetails extends Serializable {
// 权限信息
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
// 账户是否过期
boolean isAccountNonExpired();
// 账户是否被锁定
boolean isAccountNonLocked();
// 密码是否过期
boolean isCredentialsNonExpired();
// 账户是否可用
boolean isEnabled();
}
现在将AccountNonLocked设置为false
@Component
public class MyUserDetailsServer implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 实际项目中这些内容需要从数据库表中查询到
return new User(username, "123456",
true,true,true,false,
AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}
再次访问order接口效果如下:
OAuth2搭建
找到一篇非常好的文章注重的讲解了oauth2密码和客户端实现
针对密码的解析官方流程