2013-09-10 5 views
7

Ich versuche, zwei verschiedene Sicherheitskonfigurationen für verschiedene URL-Muster zu definieren, von denen eines Formularanmeldung verwendet und ein anderes die Standardauthentifizierung für eine API verwendet.Basis- und formularbasierte Authentifizierung mit Spring-Sicherheit Javaconfig

Die Lösung, die ich suche, ist ähnlich der hier erklärt http://meera-subbarao.blogspot.co.uk/2010/11/spring-security-combining-basic-and.html, aber ich würde es gerne mit Java Config tun.

Vielen Dank im Voraus.

Dies ist die Konfiguration, die ich derzeit haben:

@Configuration 
@EnableWebSecurity 
public class AppSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private UserService userService; 

    @Override 
    protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userService); 
    } 

    @Override 
    public void configure(WebSecurity web) throws Exception { 
     // Ignore any request that starts with "/resources/". 
     web.ignoring().antMatchers("/resources/**"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeUrls().antMatchers("/", "/index", "/user/**", "/about").permitAll() 
     .antMatchers("/admin/**").hasRole("ADMIN") 
     .anyRequest().authenticated() 
     .and().formLogin() 
     .loginUrl("/login") 
     .failureUrl("/login-error") 
     .loginProcessingUrl("/security_check") 
     .usernameParameter("j_username").passwordParameter("j_password") 
     .permitAll(); 

     http.logout().logoutUrl("/logout"); 
     http.rememberMe().rememberMeServices(rememberMeServices()).key("password"); 
    } 

    @Bean 
    public RememberMeServices rememberMeServices() { 
     TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices("password", userService); 
     rememberMeServices.setCookieName("cookieName"); 
     rememberMeServices.setParameter("rememberMe"); 
     return rememberMeServices; 
    } 
} 
+0

Welche Ergebnisse sehen Sie? – Taylor

+0

Derzeit habe ich nur Formularauthentifizierung mit diesem und ich kann nicht finden, wie grundlegende Authentifizierung zu einem URL-Muster wie/api/* –

Antwort

9

Die Lösung, die ich fand, war eine andere Klasse erweitert WebSecurityConfigurerAdapter innerhalb des ersten zu schaffen, wie https://github.com/spring-projects/spring-security-javaconfig/blob/master/samples-web.md#sample-multi-http-web-configuration beschrieben

Meine Lösung ist wie folgt:

@Configuration 
@EnableWebSecurity 
public class AppSecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private UserService userService; 

    @Override 
    protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(userService); 
    } 

    @Override 
    public void configure(WebSecurity web) throws Exception { 
     // Ignore any request that starts with "/resources/". 
     web.ignoring().antMatchers("/resources/**"); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.authorizeUrls().antMatchers("/", "/index", "/user/**", "/about").permitAll() 
      .antMatchers("/admin/**").hasRole("ADMIN") 
      .anyRequest().authenticated() 
      .and().formLogin() 
      .loginUrl("/login") 
      .failureUrl("/login-error") 
      .loginProcessingUrl("/security_check") 
      .usernameParameter("j_username").passwordParameter("j_password") 
      .permitAll(); 

     http.logout().logoutUrl("/logout"); 
     http.rememberMe().rememberMeServices(rememberMeServices()).key("password"); 
    } 

    @Bean 
    public RememberMeServices rememberMeServices() { 
     TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices("password", userService); 
     rememberMeServices.setCookieName("cookieName"); 
     rememberMeServices.setParameter("rememberMe"); 
     return rememberMeServices; 
    } 

    @Configuration 
    @Order(1) 
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { 

     @Override 
     protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception { 
      auth.inMemoryAuthentication().withUser("api").password("pass").roles("API"); 
     } 

     protected void configure(HttpSecurity http) throws Exception { 
      http.authorizeUrls() 
       .antMatchers("/api/**").hasRole("API") 
       .and() 
       .httpBasic(); 
     } 
    } 
} 
2

ich einfach tun es sagen würde. Geben Sie eine zweite Zeile mit authorizeUrls() an, aber für Ihre URLs, die für die Standardauthentifizierung benötigt werden. Statt formLogin()httpBasic()

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http.authorizeUrls().antMatchers("/", "/index", "/user/**", "/about").permitAll() 
    .antMatchers("/admin/**").hasRole("ADMIN") 
    .anyRequest().authenticated() 
    .and().formLogin() 
    .loginUrl("/login") 
    .failureUrl("/login-error") 
    .loginProcessingUrl("/security_check") 
    .usernameParameter("j_username").passwordParameter("j_password") 
    .permitAll(); 

    http.authorizeUrls().antMatchers("/api/*").hasRole("YOUR_ROLE_HERE").and().httpBasic(); 

    http.logout().logoutUrl("/logout"); 
    http.rememberMe().rememberMeServices(rememberMeServices()).key("password"); 
} 

So etwas Ähnliches verwenden sollte funktionieren.

Links: HttpSecurity, HttpBasicConfgurer.

+0

Es funktionierte nicht, die API behauptet, dass der Aufruf von authorizeUrls() zweimal überschreibt die vorherigen Aufrufe so es ist wahrscheinlich nicht möglich, es auf diese Weise zu tun –

0

Sie es .antMatcher("/api/**") durch Zugabe lösen kann nur nach http in Ihrem ersten Config nur /api URLs zu verwalten. Sie müssen es auf dem ersten Adapter haben:

http 
    .antMatcher("/api/*") 
    .authorizeRequests() 
     .antMatchers("^/api/.+$").hasRole("ADMIN") 
    .... 
-1

Die anderen Antworten hier relativ alt sind und zum Beispiel kann ich authorizeUrls im Frühjahr nicht 4.

In SpringBoot 1.4.0/Spring 4 finden

diese
@EnableWebSecurity 
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 
{ 
    protected void configure (HttpSecurity aHttp) throws Exception 
    {  
     aHttp.authorizeRequests().antMatchers (("/api/**")).fullyAuthenticated().and().httpBasic(); 

     aHttp.formLogin() 
     .loginPage ("/login").permitAll() 
     .and().logout().permitAll(); 
    } 
} 

Es kann mehr ellegant Möglichkeiten des Schreibens - ich arbeite immer noch auf das Verständnis, wie dieser Builder in Bezug auf die Reihenfolge funktioniert und so weiter: habe ich die Grund/form Login wie diese umgesetzt werden. Aber das hat funktioniert.

+0

Dies funktioniert nicht für mich - Versuche, auf/api/zuzugreifen, werden zum Login-Formular anstatt zur Standardauthentifizierung umgeleitet. –

+0

@JamesBaker - das OP hat nie erwähnt, dass er für Basic Auth ... PROMPTED sein muss, aber grundlegende Auth, mit dem oben genannten, funktioniert. Wenn Sie einen HTTP-Client von sort verwenden und grundlegende Berechtigungen in Ihrer Anfrage senden, funktioniert es. – ETL

0

Offensichtlich als Feder aktualisiert diese neigen dazu, in ihrer Anwendbarkeit zu verblassen. Runing Spring Cloud Starter Sicherheit 1.4.0.RELEASE das ist meine Lösung. Mein Anwendungsfall war ein bisschen anders, da ich versuche, den Aktualisierungsendpunkt mit basic auth für die Cloud-Konfiguration zu sichern und ein Gateway mit Spring-Session zu verwenden, um die Authentifizierung in allen anderen Instanzen zu übergeben.

@EnableWebSecurity 
@Configuration 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Autowired 
    public void configureGlobal1(AuthenticationManagerBuilder auth) throws Exception { 
     //try in memory auth with no users to support the case that this will allow for users that are logged in to go anywhere 
     auth.inMemoryAuthentication(); 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .httpBasic() 
       .disable() 
      .authorizeRequests() 
       .antMatchers(HttpMethod.POST, "/user").permitAll() 
       .anyRequest().authenticated() 
       .and() 
      .csrf().disable(); 
    } 

    @Bean 
    public BCryptPasswordEncoder encoder() { 
     return new BCryptPasswordEncoder(11); 
    } 

    @Configuration 
    @Order(1) 
    public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { 

     @Autowired 
     private AuthenticationProvider customAuthenticationProvider; 

     @Autowired 
     protected void configureGlobal2(AuthenticationManagerBuilder auth) throws Exception { 
      auth 
        .authenticationProvider(customAuthenticationProvider); 
     } 

     @Override 
     protected void configure(HttpSecurity http) throws Exception { 
      http 
       .httpBasic() 
        .and() 
       .authorizeRequests() 
        .antMatchers(HttpMethod.POST, "/refresh").hasRole("SUPER") 
        .and() 
       .csrf().disable(); 
     } 
    } 
} 

sehen die Federsicherheits docs zur weiteren Klärung: Spring Security

Die Grundidee ist, dass die @Order Anmerkung diktieren, was die Auth-Systeme ausgeführt werden, bestellen. No @Order bedeutet, dass es das letzte ist. Wenn der authorizeRequests() -Abschnitt nicht mit der eingehenden URL übereinstimmen kann, wird diese Konfiguration ausgeführt und die nächste versucht die Authentifizierung. Dies wird fortgesetzt, bis die Authentifizierung erfolgreich ist oder fehlschlägt.

Verwandte Themen