2015-10-06 3 views
5

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!

Antwort

3

Nach meiner Erfahrung gibt es Probleme mit mehreren WebSecurityConfigurer s mit der Sicherheitskonfiguration beim Start Unordnung.

Der beste Weg, dies zu lösen, ist, Ihre Bibliothekkonfiguration in SecurityConfigurerAdapters zu ändern, die gegebenenfalls angewendet werden kann.

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); 
    } 
} 

Sie haben dann Ihre Benutzer apply diese in ihrer eigenen Konfiguration:

@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(...)); 
    } 
} 
+2

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

+0

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

-2

Es ist definitiv das Problem bezüglich der Reihenfolge Ihrer Antmatchers oder hat keine ROLES von Benutzern angegeben, denen Sie den Zugriff auf die URL erlauben.

Was hast du über "/ restricted"?

Blockiert irgendetwas etwas unter dieser URL? Sie sollten zuerst spezifischere URLs und dann generalisierte URLs angeben.

Versuchen Sie, die obige URL richtig zu konfigurieren (oder sagen Sie mir, was es ist, damit ich Ihnen helfen kann), vielleicht "fullyAuthenticated" auch "allowAll" ROLEs auf die übergeordnete URL von "/ restricted".

+0

Es ist nicht nur eine Frage der Ordnung ist. Wenn ich dies tun: @Override protected void configure (HttpSecurity http) throws Exception { http .authorizeRequests() antMatchers ("/ **") permitAll() .und() .authorizeRequests().. .antMatchers ("/ restricted"). fullyAuthenticated(); } Dann werde ich umgeleitet, aber ich stolperte in ein CSRF-Problem (bereits funktionierende Antrieb in der Konfiguration in 'AbstractStormpathWebSecurityConfiguration'). Es scheint, dass hier 2 unabhängige Kettenfilter spielen, die nicht richtig verkettet werden. – mario

+0

Sie haben im Wesentlichen eine Kette von Sicherheitsfiltern, die sowieso in Ordnung sind. Wenn Sie mit einem CSRF-Problem konfrontiert sind, sind Ihre Benutzer noch nicht ordnungsgemäß authentifiziert, bevor Sie diese URL eingeben. Andernfalls, wenn die URL keine Authentifizierung erfordert, deaktivieren Sie CSRF einfach durch .csrf(). Disable. –

Verwandte Themen