1.1、框架设计
主要涉及两个内容:建造者和配置器,框架就是配置器对建造者进行配置主要的用法就是写一个自定义配置类,继承WebSecurityConfigurerAdapter 重写几个configure()方法,WebSecurityConfigurerAdapter web安全配置器的适配对象安全建造者—AbstractSecurityBuilder配置安全制造者—AbstractConfiguredSecurityBuilder安全配置器。
小结:
(1)看到建造者去看他的这些方法:build(); doBuild(); init(); configure(); performBuild();
(2)看到配置器去看他的这些方法:init(); config();
1.2、@EnableWebSecurity注解
@EnableWebSecurtiy注解是一个组合注解:
(1)@EnableWebFluxSecurity注解:这个注解用于项目中启动SpringSecurity,为某些请求路径开启安全认证策略;
(2)@Import注解:@Import注解导入WebSecurtiyConfiguration是为了注入这个类,在这个类中,注入了一个非常重要的bean——springSecurityFilterChain,这是Spring Secuity的核心过滤器, 这是请求的认证入口。@Import注解中导入的SpringWebMvcImportSelector和OAuth2ImportSelector是为了导入他俩中的其他bean把ImportSelector接口selectImports()方法返回的Class名称都定义为bean。ImportSelector : 返回需要导入的组件的全类名数组。
(3)@EnableGlobalAuthentication注解:@EnableGlobalAuthentication主要作用是使用@Import注解激活AuthenticationConfiguration类AuthenticationConfiguration配置类, 这个类是来配置认证相关的核心类, 这个类的主要作用是,向spring容器中注入AuthenticationManagerBuilder, AuthenticationManagerBuilder其实是使用了建造者模式, 他能建造AuthenticationManager, 这个类前面提过,是身份认证的入口。
1.3、@EnableGlobalMethodSecurity注解
作用:当我们想要开启spring方法级安全时,只需要在任何 @Configuration实例上使用 @EnableGlobalMethodSecurity 注解就能达到此目的。同时这个注解为我们提供了prePostEnabled 、securedEnabled 和 jsr250Enabled 三种不同的机制来实现同一种功能。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(jsr250Enabled = true, prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({GlobalMethodSecuritySelector.class})
@EnableGlobalAuthentication
@Configuration
public @interface EnableGlobalMethodSecurity {
boolean prePostEnabled() default false;
boolean securedEnabled() default false;
boolean jsr250Enabled() default false;
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default 2147483647;
}
prePostEnabled=true 会解锁 @PreAuthorize 和 @PostAuthorize 两个注解。从名字就可以看出@PreAuthorize 注解会在方法执行前进行验证,而 @PostAuthorize 注解会在方法执行后进行验证。
public interface UserService {
List<User> findAllUsers();
@PostAuthorize ("returnObject.type == authentication.name")
User findById(int id);
// @PreAuthorize("hasRole('ADMIN')") 必须拥有 ROLE_ADMIN 角色。
@PreAuthorize("hasRole('ROLE_ADMIN ')")
void updateUser(User user);
@PreAuthorize("hasRole('ADMIN') AND hasRole('DBA')")
void deleteUser(int id);
// @PreAuthorize("principal.username.startsWith('Felordcn')") 用户名开头为 Felordcn 的用户才能访问。
// @PreAuthorize("#id.equals(principal.username)") 入参 id 必须同当前的用户名相同。
// @PreAuthorize("#id < 10") 限制只能查询 id 小于 10 的用户
}