2013-09-10 17 views
7

Sto provando a definire due diverse configurazioni di sicurezza per diversi modelli di URL, uno dei quali utilizza l'accesso al modulo e un altro tramite l'autenticazione di base per un'API.Autenticazione di base e basata su modulo con sicurezza Spring Javaconfig

La soluzione che sto cercando è simile a quella spiegata qui http://meera-subbarao.blogspot.co.uk/2010/11/spring-security-combining-basic-and.html ma mi piacerebbe farlo usando java config.

Grazie in anticipo.

Questa è la configurazione ho attualmente:

@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

Quali risultati stai vedendo? – Taylor

+0

Attualmente ho solo l'autenticazione del modulo con questo e non riesco a trovare come aggiungere un'autenticazione di base a un modello di URL come/api/* –

risposta

9

La soluzione che ho trovato è stato quello di creare un altro estendendo WebSecurityConfigurerAdapter classe all'interno del primo, come è descritto https://github.com/spring-projects/spring-security-javaconfig/blob/master/samples-web.md#sample-multi-http-web-configuration

La mia soluzione è la seguente:

@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

direi semplicemente farlo. Specificare una seconda riga con authorizeUrls() ma per gli URL necessari con l'autenticazione di base. Invece di utilizzare 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"); 
} 

Qualcosa del genere dovrebbe funzionare.

Collegamenti: HttpSecurity, HttpBasicConfgurer.

+0

Non ha funzionato, l'API afferma che invocando authorizeUrls() due volte sovrascrive le chiamate precedenti in modo probabilmente non è possibile farlo in questo modo –

0

si può risolvere con l'aggiunta di .antMatcher("/api/**") subito dopo http nella prima configurazione per gestire solo gli URL /api. È necessario disporre sul primo adattatore:

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

Le altre risposte a qui sono relativamente vecchio e, per esempio, non riesco a trovare authorizeUrls nella primavera 4.

In SpringBoot 1.4.0/primavera 4 , ho implementato il modulo di base di login/in questo modo:

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

ci possono essere modi più ellegant di scrivere questo - sto ancora lavorando sulla comprensione di come funziona questo costruttore in termini di sequenza e così via. Ma questo ha funzionato.

+0

Questo non funziona per me: i tentativi di accesso/api/vengono reindirizzati al modulo di login piuttosto che all'autenticazione di base. –

+0

@JamesBaker - l'OP non ha mai detto che deve essere PROMETTATO per l'autenticazione di base ... ma l'autenticazione di base, con quanto sopra, funziona. Se si utilizza un client HTTP di ordinamento e si inviano credenziali di autenticazione di base nella richiesta, funziona. – ETL

0

Ovviamente come aggiornamenti di primavera questi tendono a svanire nella loro applicabilità. Running spring cloud starter security 1.4.0.RELEASE questa è la mia soluzione. Il mio caso d'uso era un po 'diverso perché sto provando a proteggere l'endpoint di aggiornamento utilizzando l'autenticazione di base per la configurazione del cloud e utilizzando un gateway con la sessione primaverile per passare l'autenticazione in tutte le altre istanze.

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

vedere la documentazione di sicurezza a molla per ulteriori chiarimenti: Spring Security

L'idea di base è che l'annotazione @Order detterà quale ordine l'autenticazione schemi vengono eseguiti. No @ Order significa che è l'ultimo. Se la sezione authorizeRequests() non può corrispondere sull'URL in arrivo, quella configurazione passerà e quella successiva tenterà l'autenticazione. Questo proseguirà fino a quando l'autenticazione avrà esito positivo o negativo.

Problemi correlati