概述
当前所有认证请求配置和应用权限配置在安全模块中,而很多权限配置是在应用模块提供的对应服务处理逻辑,这 样只有应用模块才知道的这些配置,所以要将它们抽取到应用中进行配置。
实现流程
- 创建 AuthorizeConfigurerProvider 授权配置统一接口。
- 针对每个功能模块都创建一个 AuthorizeConfigurerProvider 接口的模块权限配置实现类, 如:用户模块权限配置实现类、角色模块权限配置实现类
- 将对应权限配置抽取到对应 AuthorizeConfigurerProvider 的实现类中
- 创建一个授权配置管理者接口 AuthorizeConfigurerManager 管理所有的授权配置
- 通过 AuthorizeConfigurerManager 接口实现类,将 AuthorizeConfigureProvider 所有的授权配置实现类全部加 载到容器中。
创建授权配置提供者
方法参数是 HttpSecurity
中
authorizeRequests()
返回值
,
因为都是基于它进行授权配置的
public interface AuthorizeConfigurerProvider {
/**
* 参数为 authorizeRequests() 的返回值
* @param config
*/
void configure(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry
config);
}
创建认证放行相关授权配置实现类
- 实现 AuthorizeConfifigurerProvider 接口
- 将 SpringSecurityConfifig#confifigure 方法中关于身份认证相关请求配置抽取到这个 confifig 中,
- 指定容器加载组件顺序:@Order(Integer.MAX_VALUE) // 值越小加载越优先,值越大加载越靠后
@Component
public class CustomAuthorizeConfigurationProvider implements AuthorizeConfigurerProvider {
@Autowired
private SecurityProperties securityProperties;
@Override
public void configure(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
// 放行/login/page不需要认证可访问
config.antMatchers(securityProperties.getAuthentication().getLoginPage(),
securityProperties.getAuthentication().getImageCodeUrl(),
securityProperties.getAuthentication().getMobilePage(),
securityProperties.getAuthentication().getMobileCodeUrl() ).permitAll();
}
}
在web 创建关于系统管理模块相关的授权配置提供者
- 实现 AuthorizeConfifigurerProvider 接口
- 将 SpringSecurityConfifig#confifigure 方法中关于用户、角色、菜单模块授权配置抽取到这个 confifig 中
@Component
public class SystemAuthorizeConfigurerProvider implements AuthorizeConfigurerProvider {
@Override
public void
configure(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
config.antMatchers("/user").hasAuthority("sys:user")
.antMatchers(HttpMethod.GET, "/role")
.hasAuthority("sys:role")
.antMatchers(HttpMethod.GET, "/permission") //角色会加上前缀 ROLE_,即真实是 ROLE_ADMIN
.access("hasAuthority('sys:permission') or hasAnyRole('ADMIN')");
}
}
创建授权配置管理者
方法参数是 HttpSecurity
中
authorizeRequests()
返回值 ,它用于接收
SpringSecurityConfifig
传递过来 的。
public interface AuthorizeConfigurerManager {
void configure(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry
config);
}
创建实现类 CustomAuthorizeConfifigurationManager 实现
AuthorizeConfifigurerManager
接口,加载所有的授权配置 类,也就是AuthorizeConfifigurerProvider接口所有子类实例
@Component
public class CustomAuthorizeConfigurationManager implements AuthorizeConfigurerManager {
@Autowired
List<AuthorizeConfigurerProvider> authorizeConfigurerProviders;
@Override
public void
configure(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
for(AuthorizeConfigurerProvider provider : authorizeConfigurerProviders) {
provider.configure(config);
}
// 除了 AuthorizeConfigurerProvider 实现类中配置的,其他请求都需要身份认证
config.anyRequest().authenticated();
}
}
重构 SpringSecurityConfifig
@Configuration @EnableWebSecurity // 开启springsecurity过滤链 filter @EnableGlobalMethodSecurity(prePostEnabled = true) //开启注解方法级权限控制
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
// 配置文件参数
@Autowired
private SecurityProperties securityProperties;
@Autowired
private AuthenticationSuccessHandler customAuthenticationSuccessHandler;
@Autowired
private AuthenticationFailureHandler customAuthenticationFailureHandler;
@Autowired
private ImageCodeValidateFilter imageCodeValidateFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
/****
***
*/
// 权限相关配置管理者, 将所有授权配置管理起来了
authorizeConfigurerManager.configure(http.authorizeRequests());
}
}