Tôi đang tạo cấu hình Spring Security để sử dụng làm thư viện của bất kỳ nhà phát triển nào muốn tạo ứng dụng Springpath Spring được bảo mật bằng Spring Security.Nhiều WebSecurityConfigurerAdapter: một như một thư viện, trong những người dùng khác có thể thêm quyền truy cập bảo mật của riêng mình
Đối với điều đó tôi đã phân loại phụ WebSecurityConfigurerAdapter
và xác định các điều khiển truy cập Stormpath trong configure(HttpSecurity)
cũng như Stormpath AuthenticationProvider
bằng phương tiện configure(AuthenticationManagerBuilder)
. Tất cả điều này có thể được nhìn thấy trong lớp trừu tượng này và bê tông sub-class của nó:
@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);
}
}
Nói tóm lại, chúng tôi về cơ bản xác định cơ chế đăng nhập và đăng xuất của chúng tôi và tích hợp mã CSRF của chúng tôi để chơi độc đáo với một mùa xuân an nhân.
Tính đến thời điểm này, mọi thứ đều hoạt động OK.
Nhưng đây chỉ là "thư viện" và chúng tôi muốn người dùng xây dựng ứng dụng của riêng họ trên đầu trang của nó.
Vì vậy, chúng tôi đã tạo một ứng dụng Mẫu để minh họa cách người dùng sẽ sử dụng thư viện của chúng tôi.
Về cơ bản, người dùng sẽ muốn tạo riêng của mình WebSecurityConfigurerAdapter
. Như thế này:
@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();
}
}
Trong trường hợp này là thực sự cần thiết, WebApplicationInitializer
trông như thế này:
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, "/*");
}
}
Tất cả điều này đang khởi động lên một cách chính xác. Nếu tôi truy cập localhost:8080
Tôi thấy màn hình chào mừng. Nếu tôi truy cập localhost:8080/login
Tôi thấy màn hình đăng nhập. Nhưng, nếu tôi truy cập vào localhost:8080/restricted
, tôi sẽ được chuyển hướng đến trang đăng nhập vì chúng tôi có dòng này: http.authorizeRequests().antMatchers("/restricted").fullyAuthenticated();
. Tuy nhiên, tôi thấy trang Access Denied
.
Sau đó, nếu tôi thêm các url đăng nhập trong kiểm soát truy cập của ứng dụng, như thế này:
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().loginPage("/login")
.and()
.authorizeRequests().antMatchers("/restricted").fullyAuthenticated();
}
Nó bây giờ chuyển hướng tôi đến trang đăng nhập nhưng ngay sau khi tôi gửi các thông tin tôi nhận được một vấn đề ý nghĩa CSRF rằng tất cả cấu hình của chúng tôi không thực sự là một phần của chuỗi bộ lọc này.
Khi tôi gỡ lỗi tất cả, dường như mỗi WebApplicationInitializer
đều có cá thể riêng với Chuỗi bộ lọc riêng. Tôi hy vọng họ sẽ được nối nhau bằng cách nào đó nhưng có vẻ như nó không thực sự xảy ra ...
Bất cứ ai đã từng thử một cái gì đó như thế này?
BTW: Là người dùng giải pháp có thể làm public class SpringSecurityWebAppConfig extends StormpathWebSecurityConfiguration
thay vì SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter
. Bằng cách này, nó hoạt động nhưng tôi muốn người dùng có mã Spring Security thuần túy và mở rộng từ phân đoạn StormpathWebSecurityConfiguration
của chúng tôi từ mục tiêu đó.
Tất cả mã có thể được xem here. Thư viện an ninh Springpath Spring cho mùa xuân dưới extensions/spring/stormpath-spring-security-webmvc
. Ứng dụng mẫu sử dụng thư viện dưới examples/spring-security-webmvc
.
Nó rất đơn giản để chạy ... Bạn chỉ cần đăng ký Stormpath as explained here.Sau đó, bạn có thể kiểm tra các chi nhánh spring_security_extension_redirect_to_login_not_working
và bắt đầu ứng dụng mẫu như thế này:
$ git clone git[email protected]: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
Sau đó, bạn có thể đi đến localhost:8080/restricted
để thấy rằng bạn đang không được chuyển hướng đến trang đăng nhập.
Bất kỳ trợ giúp nào được đánh giá rất nhiều!
Đó thực sự là cách chúng tôi cuối cùng thực hiện điều đó. Để làm sạch hơn, chúng tôi đã nhập cấu hình tĩnh. Mọi thứ cuối cùng trông như sau: https://github.com/stormpath/stormpath-sdk-java/blob/master/examples/spring-security-spring-boot-webmvc-bare-bones/src/main/java/com/ stormpath/spring/boot/examples/SpringSecurityWebAppConfig.java – mario
Tệp được liên kết đã thay đổi. Mục mới: https://github.com/stormpath/stormpath-sdk-java/blob/master/examples/spring-security-webmvc/src/main/java/com/stormpath/spring/examples/SpringSecurityWebAppConfig.java – mario