2012-09-18 14 views
5

Questo è il mio scenario:SpringSecurity - Autenticazione personalizzata automatica

  • una web-app eseguire una sorta-di SSO per molte applicazioni
  • utente connesso di cliccare su un link e l'applicazione fa un post con informazioni utente (nome, pwd [inutili], ruoli) verso la corretta applicazione
  • io sono l'attuazione SpringSecurity su una di queste applicazioni di beneficiare del suo potere (autorità di sessione, metodi forniti dalle sue classi, ecc)

Quindi, ho bisogno di sviluppare un filtro personalizzato - Suppongo - che sia in grado di recuperare informazioni utente da richiesta, recuperare dal database, tramite un custom DetailsUserService, ulteriori informazioni sull'utente (email, ecc ...) e quindi eseguire l'autenticazione dell'utente, in base al ruolo recuperato dalla richiesta.

Stavo guardando i filtri Pre-Authentication, ma non sono sicuro che sia la scelta giusta. Sembra che questi oggetti siano usati quando il principal è già in sessione, messo da un precedente machanism di autenticazione (giusto?).

credo che, una volta identificato il filtro corretto, avrei bisogno di eseguire all'interno di qualcosa di simile a:

GrantedAuthority[] ga= new GrantedAuthority[1]; 
ga[0] = new GrantedAuthorityImpl(myUser.getRole()); 

SecurityContext sc = SecurityContextHolder.getContext(); 
Authentication a = new UsernamePasswordAuthenticationToken(userName, userPwd, ga); 
a = authenticationManager.authenticate(a); 
sc.setAuthentication(a); 

È giusta direzione per risolvere il mio problema? Hai suggerimenti per aiutarmi a trovare ciò che manca?

Grazie a tutti,

Luca

AGGIUNTA:

Hi Xearxess! Scusa se ti disturbo ancora ma sembra che la traduzione del tuo codice in base a SpringSecurity 2.0.4 sia più difficile di quanto pensassi: S Il problema è l'XML ... Ho provato una configurazione diversa ma mi sono imbattuto sempre in problemi di namespace, attributi mancanti , ecc ...

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:security="http://www.springframework.org/schema/security" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"> 

    <security:http> 
     <security:intercept-url pattern="/**" access="isAuthenticated()" /> 
     <security:logout logout-url="/logout" logout-success-url="http://milan-ias-vs.usersad.everis.int/DMTest/" invalidate-session="true" /> 
     <security:custom-filter position="PRE_AUTH_FILTER" ref="preAuthenticatedProcessingFilter" /> 
    </security:http> 

    <bean id="preAuthenticatedProcessingFilter" class="it.novartis.ram.authentication.PreAuthenticatedProcessingFilter"> 
     <custom-filter position="PRE_AUTH_FILTER"/> 
     <property name="authenticationManager" ref="authenticationManager" /> 
    </bean> 

    <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider"> 
     <property name="preAuthenticatedUserDetailsService"> 
      <bean class="it.novartis.ram.authentication.PreAuthenticatedUserDetailsService" /> 
     </property> 
    </bean> 

    <security:authentication-manager alias="authenticationManager"> 
     <security:authentication-provider ref="preauthAuthProvider" /> 
    </security:authentication-manager> 

</beans> 

Le 2 righe che fanno riferimento elemento CUSTOM-FILTER sono due mete differenti, entrambi firmati come errore. Come posso specificare la posizione del mio filtro come una proprietà?

Anche il riferimento del provider di autenticazione sulla definizione del gestore di autenticazione è contrassegnato come errore. Penso di aver bisogno di specificarlo come una proprietà, giusto?

Spero mi puoi dare l'ultima spinta;) Grazie ancora,

Luca

risposta

11

Sì, scenari pre-autenticazione sono esattamente quello che stanno cercando.

Sembra che coloro oggetto dovrebbero essere utilizzati quando il preside è già in sessione, messo da qualche precedente machanism autenticazione (è giusto?).

Non proprio, è possibile utilizzare la pre-autenticazione per creare PreAuthenticatedAuthenticationToken dalla richiesta, come si desidera. Solo do few things I described in another question.

Prima estendono AbstractPreAuthenticatedProcessingFilter avere username e ruoli da richiesta:

public class MyPreAuthenticatedProcessingFilter 
    extends AbstractPreAuthenticatedProcessingFilter { 

    public MyPreAuthenticatedProcessingFilter(
     AuthenticationManager authenticationManager) { 
    setAuthenticationDetailsSource(new MyAuthenticationDetailsSource()); 
    } 

    @Override 
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) { 
    return "Anonymous"; 
    } 

    @Override 
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) { 
    return "N/A"; 
    } 

    public static class MyAuthenticationDetailsSource implements 
     AuthenticationDetailsSource<HttpServletRequest, MySessionUserDetails> { 
    // roles probably should be encrypted somehow 
    static final String ROLES_PARAMETER = "pre_auth_roles"; 

    @Override 
    public MySessionUserDetails buildDetails(HttpServletRequest req) { 
     // create container for pre-auth data 
     return new MySessionUserDetails(req.getParameter(ROLES_PARAMETER)); 
    } 
    } 
} 

MySessionUserDetails classe dividerà molla con ruoli nella Lista di SimpleGrantedAuthority o qualsiasi altra GrantedAuthority attuazione. Inoltre, l'elenco è consigliato e superiore a GrantedAuthority[].

In secondo luogo, l'attuazione AuthenticationUserDetailsService:

public class MyPreAuthenticatedUserDetailsService implements 
    AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> { 

    @Override 
    public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) 
     throws UsernameNotFoundException { 
    MySessionUserDetails sessionUserDetails = 
     (MySessionUserDetails) token.getDetails(); 
    List<GrantedAuthority> authorities = sessionUserDetails.getAuthorities(); 
    return new User(token.getName(), "N/A", true, true, true, true, authorities); 
    } 
} 

Poi, nel tuo XML collegare blocchi insieme:

<security:http use-expressions="true"> 
    <security:intercept-url pattern="/**" access="isAuthenticated()" /> 
    <security:custom-filter position="PRE_AUTH_FILTER" 
     ref="myPreAuthenticationFilter" /> 
</security:http> 

<bean id="myPreAuthenticationFilter" 
    class="com.example.MyPreAuthenticatedProcessingFilter"> 
    <property name="authenticationManager" ref="authenticationManager" /> 
</bean> 

<bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider"> 
    <property name="preAuthenticatedUserDetailsService"> 
    <bean class="com.example.MyPreAuthenticatedUserDetailsService" /> 
    </property> 
</bean> 

<security:authentication-manager alias="authenticationManager"> 
    <security:authentication-provider ref="preauthAuthProvider" /> 
</security:authentication-manager> 

E voilà! Dovresti avere l'identità autenticata da User da utilizzare nella tua applicazione.

Codice che ho scritto qui richiede Spring Security 3.1 che consiglio vivamente se si sta per usarlo (richiede requrire Spring 3.0.7+). Inoltre, Spring Security reference manual è tuo amico!

+0

Grazie mille Xaerxess! Purtroppo siamo bloccati con Spring 2.5.6 e Spring Security 2.0.4, ma i tuoi suggerimenti mi aiuteranno;) – Dolfiz

+0

Peccato, Spring 3 è molto meglio, generico e ha una grande documentazione. Ma una grande quantità di codice sopra può essere trasferita a 2.X (senza generici, per esempio). – Xaerxess

+0

È davvero un peccato! Ma il codice che hai scritto mi aiuterà. Grazie ancora e buon divertimento con il tuo bambino;) – Dolfiz

8

Per motivi di completezza, in Spring Security 4 le cose sono leggermente cambiate. Ad esempio, la configurazione Java è altamente raccomandata. In questo modo, è più facile integrarsi con Spring Boot.

Segue la configurazione Java che è equivalente alla configurazione XML fornita nelle risposte precedenti.

@Configuration 
@EnableWebSecurity 
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http.addFilterBefore(customAuthFilter(), AbstractPreAuthenticatedProcessingFilter.class) 
      .authenticationProvider(preauthAuthProvider()) 
      .authorizeRequests() 
      .anyRequest().authenticated(); 
    } 

    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(preauthAuthProvider()); 
    } 

    @Bean 
    public PreAuthenticatedAuthenticationProvider preauthAuthProvider() { 
     PreAuthenticatedAuthenticationProvider preauthAuthProvider = 
      new PreAuthenticatedAuthenticationProvider(); 
       preauthAuthProvider.setPreAuthenticatedUserDetailsService(
        userDetailsServiceWrapper()); 
     return preauthAuthProvider; 
    } 

    @Bean 
    public OnlyRolesPreAuthenticatedUserDetailsService userDetailsServiceWrapper() { 
     OnlyRolesPreAuthenticatedUserDetailsService service = 
      new MyPreAuthenticatedUserDetailsService(); 
     return service; 
    } 

    @Bean 
    public MyPreAuthenticatedProcessingFilter customAuthFilter() throws Exception { 
     MyPreAuthenticatedProcessingFilter filter = new MyPreAuthenticatedProcessingFilter(); 
     filter.setAuthenticationManager(authenticationManager()); 
     return filter; 
    } 
} 

Penso che il codice di cui sopra vale la pena, perché esempi in internet sono molto semplici e la documentazione primavera manca di tali dettagli.

+0

Grazie mille! Non ho trovato da nessuna parte una spiegazione con la configurazione in Java – encastellano

+0

Felice di aiutarti. –

Problemi correlati