权限校验会调用 DelegatingReactiveAuthorizationManager -> check方法。DelegatingReactiveAuthorizationManager 里的mappings保存的是pathMatcher和对应的权限。
思路是拿到mappings,每次清空再重新添加。
把ServerHttpSecurity里的authorizeExchangeSpec替换为自定义的,authorizeExchangeSpec的configure方法里创建AuthorizationWebFilter的时候,将自定义mappings传入,替换默认的。
// 路径,权限对应关系 List> mappings = new CopyOnWriteArrayList<>(); @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) throws Exception { mappings.add(new ServerWebExchangeMatcherEntry(ServerWebExchangeMatchers.pathMatchers("/user/list"), AuthorityReactiveAuthorizationManager.hasAnyRole("admin"))); ServerHttpSecurity.AuthorizeExchangeSpec exchangeSpec = http.new AuthorizeExchangeSpec(); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(ServerHttpSecurity.AuthorizeExchangeSpec.class); enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> { if (method.equals(ServerHttpSecurity.AuthorizeExchangeSpec.class.getDeclaredMethod("configure", ServerHttpSecurity.class))) { Constructor constructor = DelegatingReactiveAuthorizationManager.class.getDeclaredConstructor(List.class); constructor.setAccessible(true); DelegatingReactiveAuthorizationManager manager = constructor.newInstance(mappings); AuthorizationWebFilter result = new AuthorizationWebFilter(manager); http.addFilterAt(result, SecurityWebFiltersOrder.AUTHORIZATION); return null; } else { return methodProxy.invoke(exchangeSpec, objects); } }); ServerHttpSecurity.AuthorizeExchangeSpec authorizeExchangeSpec = (ServerHttpSecurity.AuthorizeExchangeSpec) enhancer.create(new Class[]{ServerHttpSecurity.class}, new Object[]{http}); Field field = ServerHttpSecurity.class.getDeclaredField("authorizeExchange"); field.setAccessible(true); // 替换http里的authorizeExchangeSpec field.set(http, authorizeExchangeSpec); http.authorizeExchange() .formLogin().disable() .csrf().disable() .cors().disable() .oauth2ResourceServer() .accessDeniedHandler(XXXXXX) .authenticationEntryPoint(XXXXXX) .opaqueToken().introspector(XXXXXX); return http.build(); }



