懒惰运行时初始化Spring安全+重新加载Spring安全配置
Spring通常会在启动应用程序时急切地加载Spring安全配置。我正在将OAuth与Spring Security一起使用
我维护了一个配置表,用于存储与SSO相关的值(如jwk-url、Client_id、Client_Secret)。管理员用户将通过同一Spring Boot应用程序中的CRUD填充此值。 那么只有jwk-url可以在Spring安全配置(refer below code - jwkSetUri(...))
中进行配置。这在应用程序启动时不可用。
因此,我希望在将值加载到表中之后初始化Spring安全配置,就像运行时的延迟加载(@Lazy)一样。我知道如何延迟加载常规类/服务。
但我仍然不确定如何在运行时调用
configure(HttpSecurity http)
方法以及如何 为HttpSecurity参数赋值。当我像在运行时延迟加载一样尝试调用new ResourceServerConfiguration()时,我没有看到调用了configuration()方法。(或者)无论何时需要,这个类都需要维护为Bean和延迟加载。但仍不确定如何在代码中调用CONFigure()。另一个问题是,如果管理员更改了jwk url,如何在运行时刷新/重新加载Spring安全配置。则只有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
}
}
我已经引用了这些链接。但这对我的目的没有帮助。如有任何帮助,我们将不胜感激。
How do I lazy load Spring Security?
How to reload the Configure method of WebSecurityConfigurerAdapter when the application is up and running
Modify Spring Security Config at Runtime
Configure Spring HTTP Security at Runtime
解决方案
请选中此链接Customizing CORS Filtering at Runtime,该链接包含与您相关的类似用例,但对于他来说,他需要动态更改允许的来源。他们决定创建一个新的筛选器并简单地扩展OncePerRequestFilter。
考虑检查您的用例的OAuth2ResourceServerProperties。
更新: 在此方案中尝试使用此代码:
另一件事是,如果管理员更改了jwk url,如何在运行时刷新/重新加载Spring安全配置。则只有Spring安全配置才能使更改生效。
@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);
}
希望此信息能帮助您。
相关文章