Ich erstelle eine Spring Security-Konfiguration, die von jedem Entwickler als Bibliothek verwendet werden soll, die eine von Spring Security gesicherte Stormpath Spring-Anwendung erstellen möchte.Mehrere WebSecurityConfiguratorAdapter: eine als Bibliothek, in den anderen Benutzern können ihre eigenen Sicherheitszugriff hinzufügen
Dafür habe ich Unter eingestuft WebSecurityConfigurerAdapter
und definiert die Stormpath Zugang sowie die Stormpath in configure(HttpSecurity)
Steuert AuthenticationProvider
mittels configure(AuthenticationManagerBuilder)
. All dies kann in dieser abstrakten Klasse und ihre konkrete Unterklasse zu sehen:
@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);
}
}
Kurz gesagt, wir werden unsere Anmelde- und Abmeldemechanismen im Grunde die Definition und die Integration unserer CSRF Code schön mit Spring Security ist ein zu spielen.
Bis zu diesem Punkt funktioniert alles in Ordnung.
Aber das ist nur die "Bibliothek" und wir wollen, dass die Benutzer ihre eigenen Anwendungen darauf aufbauen.
Also haben wir eine Beispielanwendung erstellt, um zu demonstrieren, wie ein Benutzer unsere Bibliothek benutzt.
Grundsätzlich Benutzer möchten ihre eigene WebSecurityConfigurerAdapter
erstellen. Wie folgt aus:
@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();
}
}
Falls dies tatsächlich benötigt wird, sieht die WebApplicationInitializer
wie folgt aus:
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, "/*");
}
}
diesen Code bootet Alle oben. Wenn ich zu localhost:8080
gehe, sehe ich den Begrüßungsbildschirm. Wenn ich auf localhost:8080/login
gehe, sehe ich den Login-Bildschirm. Aber wenn ich zu localhost:8080/restricted
gehe, sollte ich auf die Anmeldeseite umgeleitet werden, da wir diese Zeile haben: http.authorizeRequests().antMatchers("/restricted").fullyAuthenticated();
. Allerdings sehe ich stattdessen die Access Denied
Seite.
Dann, wenn ich hinzufügen, die Login-URL in der Zugangskontrolle App, wie folgt aus:
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().loginPage("/login")
.and()
.authorizeRequests().antMatchers("/restricted").fullyAuthenticated();
}
Es jetzt leitet mich auf die Login-Seite, aber sobald ich die Anmeldeinformationen einreichen erhalte ich eine CSRF Problem Bedeutung dass unsere gesamte Konfiguration nicht Teil dieser Filterkette ist.
Wenn ich alles debugge, scheint es, dass jeder WebApplicationInitializer
eine eigene Instanz mit einer eigenen Filterkette hat. Ich würde erwarten, dass sie irgendwie verkettet werden, aber es scheint, dass es nicht wirklich geschieht ...
Wer hat jemals so etwas probiert?
BTW: Als Workaround können Benutzer public class SpringSecurityWebAppConfig extends StormpathWebSecurityConfiguration
statt SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter
tun. Auf diese Weise funktioniert es, aber ich möchte, dass Benutzer reinen Spring Security-Code haben und von unserem StormpathWebSecurityConfiguration
abweichen, der von diesem Ziel abweicht.
Der gesamte Code kann here gesehen werden. Die Stormpath Spring Security Bibliothek für das Frühjahr ist unter extensions/spring/stormpath-spring-security-webmvc
. Die Beispielanwendung, die die Bibliothek verwendet, befindet sich unter examples/spring-security-webmvc
.
Es ist sehr einfach zu ... Sie müssen nur zu Stormpath as explained here registrieren.Dann können Sie die spring_security_extension_redirect_to_login_not_working
Zweig Kasse und die Beispielanwendung wie folgt beginnen:
$ git clone [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
Dann können Sie zu localhost:8080/restricted
gehen, um zu sehen, dass Sie nicht auf die Login-Seite umgeleitet werden.
Jede Hilfe wird sehr geschätzt!
Das ist eigentlich die Art und Weise, wie wir das endlich umgesetzt haben. Um sauberer zu machen, haben wir den Konfigurator statisch importiert. Die Dinge sehen endlich so aus: https://github.com/stormpath/stormpath-sdk-java/blob/master/examples/spring-security-spring-boot-webmvc-bares-bones/src/main/java/com/ stormpath/spring/boot/examples/SpringSecurityWebAppConfig.java – mario
Die verknüpfte Datei wurde geändert. Neu: https://github.com/stormpath/stormpath-sdk-java/blob/master/examples/spring-security-webmvc/src/main/java/com/stormpath/spring/examples/SpringSecurityWebAppConfig.java – mario