在运行时延迟初始化 spring 安全性 + 重新加载 spring 安全性配置

ARo*_*ods 7 java spring spring-security spring-boot spring-security-oauth2

Spring 通常在启动应用程序时急切地加载 Spring 安全配置。我在 Spring Security 中使用 OAuth

我正在维护一个用于存储 SSO 相关值(如 jwk-url、client_id、client_secret)的配置表。该值将由管理员用户通过 CRUD 在同一个 Spring Boot 应用程序中填充。

那么只有 jwk-url 可以在 Spring 安全配置中进行配置(refer below code - jwkSetUri(...))。这在应用程序启动时不可用。

所以我想在将值加载到表中后初始化 spring 安全配置,就像运行时的​​延迟加载(@Lazy)一样。我知道如何延迟加载常规类/服务。

  1. 但是我仍然不确定如何configure(HttpSecurity http)在运行时调用该方法以及如何传递 HttpSecurity 参数。当我在运行时尝试像延迟加载一样调用new ResourceServerConfiguration()时,我没有看到 configure() 方法被调用。(或者)这个类需要在需要时作为 bean 和延迟加载来维护。但仍然不确定如何在代码中调用 configure()。

  2. 另一件事是如何在运行时刷新/重新加载 spring 安全配置,如果管理员更改了 JWK url。那么只有 spring 安全配置才能使更改生效。

@Configuration
@EnableWebSecurity
public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter {
    
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.cors()
                .and()
                .csrf().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .oauth2ResourceServer()
                .authenticationEntryPoint(oAuth2AuthenticationEntryPoint)
                .accessDeniedHandler(oAuth2AccessDeniedHandler)
                .jwt()
                 // Some Auth server URL which would be fetch from table
                .jwkSetUri(ssoConfigService.getActiveSSOCertificateURL()); 
                 // Eg. http://localhost:8090/auth/realms/demo-app/protocol/openid-connect/certs
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经提到了这些链接。但这对我的目的没有帮助。任何帮助,将不胜感激。

如何延迟加载 Spring Security?

如何在应用程序启动并运行时重新加载 WebSecurityConfigurerAdapter 的 Configure 方法

在运行时修改 Spring Security Config

在运行时配置 Spring HTTP Security

Wil*_*nta 0

请检查此链接在运行时自定义 CORS 过滤,其中包括与您相关的类似用例,但对于他来说,他需要动态更改允许的来源。他们决定创建一个新的过滤器并简单地扩展 OncePerRequestFilter。

请考虑检查您的用例的OAuth2ResourceServerProperties

更新: 在这种情况下尝试使用以下代码:

另一件事是,如果管理员更改了 JWK url,如何在运行时刷新/重新加载 spring 安全配置。然后只有spring security配置才能使更改生效。

 @Override
    public void configure(HttpSecurity http) throws Exception {
        http.cors()
                .and()
                .csrf().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                .authorizeRequests()
                .anyRequest().authenticated()

                // TODO: test with and without this and check if work for you
                .and()
                .oauth2ResourceServer()
                .authenticationEntryPoint(oAuth2AuthenticationEntryPoint)
                .accessDeniedHandler(oAuth2AccessDeniedHandler)
                .jwt()
                // Some Auth server URL which would be fetch from table
                .jwkSetUri(ssoConfigService.getActiveSSOCertificateURL());
        // Eg. http://localhost:8090/auth/realms/demo-app/protocol/openid-connect/certs

        http.addFilterBefore(new OncePerRequestFilter() {
            // Every time a request occur, this method will be called.
            @Override
            protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {

                try {
                    http.oauth2ResourceServer()
                            .authenticationEntryPoint(oAuth2AuthenticationEntryPoint)
                            .accessDeniedHandler(oAuth2AccessDeniedHandler)
                            .jwt()
                            // Some Auth server URL which would be fetch from table
                            .jwkSetUri(ssoConfigService.getActiveSSOCertificateURL());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, BasicAuthenticationFilter.class);
    }
Run Code Online (Sandbox Code Playgroud)

我希望这些信息可以帮助您。