PIGCLOUD
java 8/17 maven 3.8+ redis 3.2+ mysql 5.7.8+ idea 2019 nodejs = v16
1 nacos: module: pig-register path: /src/main/java/PigNacosApplication.java
2 用户管理 module: pig-upms/pig-upms-biz path: /src/main/java/PigApplication.java
3 认证中心 module: pig-auth
4 网关 module: pig-gateway
统一入口:集群入口 服务发现:服务列表和实体信息以及路由规则
rockterMQ rabbitMQ 协议 MQTT
seatas
OncePerRequestFilter
是 Spring 框架中一个非常重要的过滤器基类,它确保在一次完整的 HTTP 请求中,无论请求经过多少次内部转发,过滤器的逻辑都只会被执行一次。
OncePerRequestFilter
类是一个实现了javax.servlet.Filter
接口的抽象类。它保证了一次外部请求只执行一次过滤方法,对于服务器内部之间的 forward 请求,不会再次执行过滤方法。
身份验证、日志记录
spring security oauth2
- authentication
- authorization
- protected against common attacks
- CSRF
- HTTP HEADERS
- HTTP Requests
spring-projects/spring-security-samples · GitHub
spring-boot-starter-security
- 保护应用程序 URL,要求对应用程序的任何交互进行身份认证。
- 程序启动时生成一个默认用户“user”
- 生成一个默认的随机密码,并降次密码记录在控制台上
- 生成默认的登录表单和注销页面
- 提供基于表单的登录和注销流程
- 对于 Web 请求,重定向到登录页面
- 对于服务请求,返回 401 未经授权
- 处理跨站请求伪造 (CSRF,)
- 处理会话劫持攻击
- 写入 Strict-Transport-Security 以确保 HTTPS
- 写入 X-Content-Type-Options 处理嗅探攻击
- 写入 Cache Control 头保护经过身份验证的资源
- 写入 X-Frame-Options 处理点击劫持攻击
org.springframework.security.web.SecurityFilterChain
org.springframework.security.web.DefaultSecurityFilterChain
org.springframework.boot.autoconfigure.security.SecurityProperties
spring.security.user.name: user
spring.security.user.password: 123
Java Sercurity Configuration
authentication
- 读取用户
org.springframework.security.core.userdetails.UserDetailsService@loadUserByUsername
org.springframework.security.provisioning.UserDetailsManager
InMemoryUserDetailsManager
基于内存的认证流程
- 程序启动时
- 创建 InMemoryUserDetailsManager 对象
- 创建 User 对象,封装用户名、密码
- 使用 InMemoryUserDetailsManager 降 User 存入内存
- 校验用户时
- 开始认证 UsernamePasswordAuthenticationFilter@attemptAuthentication
- 读取内存中的用户信息进行比较 AbstractUserDetailsAuthenticationProvider@authenticate
- 比较密码 DaoAuthenticationProvider@additionalAuthenticationChecks
- 成功认证 AbstractUserDetailsAuthenticationProvider@createSuccessAuthentication
基于 DB 的认证流程
// entity
class UserDo {
private Integer id;
private String username;
private String password;
private Boolean enable;
}
// dao
@Mapper
inteface UserDoMapper extends BaseMapper<User> {}
// service
inteface UserDoserice {}
@Service
Class UserDoServiceImpl implement UserDoService {}
// controller
@RestController
class UserDoController {
@Resource
private UserDoService userDoService;
}
class DBUserDetailsManager implements UserDetailsManager, UserDetailsPasswordManager {
@Resource
private UserDoMapper userDoMapper;
@Override
void createUser(UserDetails o) {
User.
}
@Override
void updateUser(UserDetails var1) {
}
@Override
void deleteUser(String var1) {
}
@Override
void changePassword(String var1, String var2) {
}
@Override
boolean userExists(String var1) {
}
@Override
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException {
UserDo o = userDoMapper.selectOne(Wrappers.<User>query().eq("username", var1));
if (o == null) throw new UsernameNotFoundException(var1);
return new User(
o.getoname(),
o.getPassword(),
o.isEnabled(),
o.isAccountNonExpired(),
o.isCredentialsNonExpired(),
o.isAccountNonLocked(),
o.getAuthorities()
);
}
}
@Configuration
class SecurityConfiguration {
@Bean
public UserDetailService() {
return new DBUserDetailsManager();
}
// default
@Bean
public SecurityFilterBean filterChain(HttpSecurity http) throw Exception {
http.authorizeHttpRequests(authorize ->
// 所有请求开启授权保护
authorize.anyRequest()
// 已认证的请求会被自动授权
.authenticated()
// 默认表单进行认证
).formLogin(Customizer.withDefaults())
formLogin(Customizer.withDefaults())
// 使用基本授权方式
.httpBasic(Customizer.withDefaults());
// 关闭 csrf 防御
http.csrf(e -> e.disable());
return http.build();
}
// 自定义登录页
@Bean
public SecurityFilterBean filterChain(HttpSecurity http) throw Exception {
http.authorizeHttpRequests(authorize ->
authorize.anyRequest()
.authenticated()
).formLogin(Customizer.withDefaults())
// 自定义登录页路径并许可访问
formLogin(e -> e.loginPage("/login").permitAll()
// 自定义表单参数
.usernameParameter("username")
.passwordParameter("password")
// 定义错误 url,默认地址 login?error
.failureUrl('login?failure')
)
return http.build();
}
}
加盐密码
自适应单向函数
故意占用资源(使用大量的CPU、内存或其他资源),自适应单向函数可调整“工作因子”改变执行时间。
bcrypt, PBKDF2, scrypt, argon2
PasswordEncoder
PasswordEncoder encoder = new BCryptPasswordEncoder(4);
String result = encoder.encode("ssss");
Assert.isTrue(encoder.matches("password", result), "密码不一致");