gpt4 book ai didi

spring - 多个WebSecurityConfigurerAdapter : one as a library,中其他用户可以添加自己的安全访问权限

转载 作者:行者123 更新时间:2023-12-02 09:28:48 24 4
gpt4 key购买 nike

我正在创建一个 Spring Security 配置,供任何想要创建受 Spring Security 保护的 Stormpath Spring 应用程序的开发人员用作库。

为此,我对 WebSecurityConfigurerAdapter 进行了子分类并在configure(HttpSecurity)中定义了Stormpath访问控制以及 Storm 路径 AuthenticationProvider通过configure(AuthenticationManagerBuilder) 。这一切都可以在这个抽象类及其具体子类中看到:

@Order(99)
public abstract class AbstractStormpathWebSecurityConfiguration extends WebSecurityConfigurerAdapter {

//Removed properties and beans for the sake of keeping focus on the important stuff

/**
* The pre-defined Stormpath access control settings are defined here.
*
* @param http the {@link HttpSecurity} to be modified
* @throws Exception if an error occurs
*/
protected void configure(HttpSecurity http, AuthenticationSuccessHandler successHandler, LogoutHandler logoutHandler)
throws Exception {

if (loginEnabled) {
http
.formLogin()
.loginPage(loginUri)
.defaultSuccessUrl(loginNextUri)
.successHandler(successHandler)
.usernameParameter("login")
.passwordParameter("password");
}

if (logoutEnabled) {
http
.logout()
.invalidateHttpSession(true)
.logoutUrl(logoutUri)
.logoutSuccessUrl(logoutNextUri)
.addLogoutHandler(logoutHandler);

}

if (!csrfProtectionEnabled) {
http.csrf().disable();
} else {
//Let's configure HttpSessionCsrfTokenRepository to play nicely with our Controllers' forms
http.csrf().csrfTokenRepository(stormpathCsrfTokenRepository());
}
}

/**
* Method to specify the {@link AuthenticationProvider} that Spring Security will use when processing authentications.
*
* @param auth the {@link AuthenticationManagerBuilder} to use
* @param authenticationProvider the {@link AuthenticationProvider} to whom Spring Security will delegate authentication attempts
* @throws Exception if an error occurs
*/
protected void configure(AuthenticationManagerBuilder auth, AuthenticationProvider authenticationProvider) throws Exception {
auth.authenticationProvider(authenticationProvider);
}
}

@Configuration
public class StormpathWebSecurityConfiguration extends AbstractStormpathWebSecurityConfiguration {

//Removed beans for the sake of keeping focus on the important stuff

@Override
protected final void configure(HttpSecurity http) throws Exception {
configure(http, stormpathAuthenticationSuccessHandler(), stormpathLogoutHandler());
}

@Override
protected final void configure(AuthenticationManagerBuilder auth) throws Exception {
configure(auth, super.stormpathAuthenticationProvider);
}
}

简而言之,我们基本上定义了登录和注销机制,并集成了我们的 CSRF 代码,以便与 Spring Security 的代码很好地配合。

到目前为止,一切正常。

但这只是“库”,我们希望用户在其上构建自己的应用程序。

因此,我们创建了一个示例应用程序来演示用户将如何使用我们的库。

基本上用户会想要创建自己的WebSecurityConfigurerAdapter 。像这样:

@EnableStormpathWebSecurity
@Configuration
@ComponentScan
@PropertySource("classpath:application.properties")
@Order(1)
public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {

/**
* {@inheritDoc}
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/restricted").fullyAuthenticated();
}

}

如果确实需要,WebApplicationInitializer看起来像这样:

public class WebAppInitializer implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext sc) throws ServletException {

AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(SpringSecurityWebAppConfig.class);
context.register(StormpathMethodSecurityConfiguration.class);
sc.addListener(new ContextLoaderListener(context));

ServletRegistration.Dynamic dispatcher = sc.addServlet("dispatcher", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");

//Stormpath Filter
FilterRegistration.Dynamic filter = sc.addFilter("stormpathFilter", new DelegatingFilterProxy());
EnumSet<DispatcherType> types =
EnumSet.of(DispatcherType.ERROR, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);
filter.addMappingForUrlPatterns(types, false, "/*");

//Spring Security Filter
FilterRegistration.Dynamic securityFilter = sc.addFilter(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, DelegatingFilterProxy.class);
securityFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
}
}

所有这些代码都能正确启动。如果我去localhost:8080我看到欢迎屏幕。如果我去localhost:8080/login我看到登录屏幕。但是,如果我去localhost:8080/restricted我应该被重定向到登录页面,因为我们有这一行:http.authorizeRequests().antMatchers("/restricted").fullyAuthenticated(); 。但是我看到 Access Denied页面代替。

然后,如果我在应用程序的访问控制中添加登录网址,如下所示:

protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().loginPage("/login")
.and()
.authorizeRequests().antMatchers("/restricted").fullyAuthenticated();
}

它现在将我重定向到登录页面,但一旦我提交凭据,我就会遇到 CSRF 问题,这意味着我们的所有配置实际上并不是此过滤器链的一部分。

当我调试所有内容时,似乎每个 WebApplicationInitializer有自己的实例和自己的过滤器链。我希望它们以某种方式连接起来,但似乎它实际上并没有发生......

有人尝试过这样的事情吗?

顺便说一句:作为解决方法,用户可以执行 public class SpringSecurityWebAppConfig extends StormpathWebSecurityConfiguration而不是SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter 。这样它就可以工作,但我希望用户拥有纯 Spring Security 代码并从我们的 StormpathWebSecurityConfiguration 扩展。偏离了该目标。

所有代码可见here 。 Spring 的 Stormpath Spring Security 库位于 extensions/spring/stormpath-spring-security-webmvc 下。使用该库的示例应用程序位于examples/spring-security-webmvc下.

运行起来非常简单...你只需要注册到Stormpath as explained here 。然后您可以查看spring_security_extension_redirect_to_login_not_working分支并启动示例应用程序,如下所示:

$ git clone git@github.com:mrioan/stormpath-sdk-java.git
$ git checkout spring_security_extension_redirect_to_login_not_working
$ mvn install -DskipTests=true
$ cd examples/spring-security-webmvc
$ mvn jetty:run

然后您可以前往localhost:8080/restricted查看您没有被重定向到登录页面。

非常感谢任何帮助!

最佳答案

根据我的经验,多个 WebSecurityConfigurer 在启动时扰乱安全配置会出现问题。

解决此问题的最佳方法是将您的库配置放入可在适当情况下应用的 SecurityConfigurerAdapters 中。

public class StormpathHttpSecurityConfigurer
extends AbstractStormpathWebSecurityConfiguration
implements SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> {

//Removed beans for the sake of keeping focus on the important stuff

@Override
protected final void configure(HttpSecurity http) throws Exception {
configure(http, stormpathAuthenticationSuccessHandler(), stormpathLogoutHandler());
}
}

public class StormpathAuthenticationManagerConfigurer
extends AbstractStormpathWebSecurityConfiguration
implements SecurityConfigurer<AuthenticationManager, AuthenticationManagerBuilder> {

//Removed beans for the sake of keeping focus on the important stuff

@Override
protected final void configure(AuthenticationManagerBuilder auth) throws Exception {
configure(auth, super.stormpathAuthenticationProvider);
}
}

然后,您可以让用户在自己的配置中应用这些内容:

@EnableStormpathWebSecurity
@Configuration
@ComponentScan
@PropertySource("classpath:application.properties")
@Order(1)
public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/restricted").fullyAuthenticated()
.and()
.apply(new StormPathHttpSecurityConfigurer(...))
;
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.apply(new StormPathAuthenticationManagerConfigurer(...));
}
}

关于spring - 多个WebSecurityConfigurerAdapter : one as a library,中其他用户可以添加自己的安全访问权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32959731/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com