2012-07-26 3 views
6

Attualmente sto utilizzando la sicurezza di primavera e le annotazioni per proteggere le chiamate di metodo. Ora voglio cambiare il token di autenticazione per una chiamata al metodo come lo run-as authentication replacement di spring security mi permette di fare.Cambia il contesto di sicurezza per la chiamata al metodo con sicurezza a molla

Posso configurare la sostituzione su una base di metodo? Per annotazione, espressione SpEL .... In caso contrario, sarebbe possibile capire in runAsManager quale metodo viene chiamato? Come configurare gli attributi di sicurezza per un oggetto protetto, a tutti?

risposta

1

Ho risolto questo problema implementando il mio RunAsManager che verifica un'annotazione personalizzata sul metodo richiamato e restituisce il token appropriato.

funziona benissimo.

6

Ho pubblicato a detailed article sull'implementazione di Run-As in combinazione con @PreAuthorize.

1) Implementare il proprio RunAsManager che crea l'Authentication da utilizzare durante l'esecuzione del metodo in base a qualsiasi logica personalizzata. L'esempio che segue utilizza un'annotazione personalizzata che fornisce il ruolo in più:

public class AnnotationDrivenRunAsManager extends RunAsManagerImpl { 

     @Override 
     public Authentication buildRunAs(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) { 
      if(!(object instanceof ReflectiveMethodInvocation) || ((ReflectiveMethodInvocation)object).getMethod().getAnnotation(RunAsRole.class) == null) { 
       return super.buildRunAs(authentication, object, attributes); 
      } 

      String roleName = ((ReflectiveMethodInvocation)object).getMethod().getAnnotation(RunAsRole.class).value(); 

      if (roleName == null || roleName.isEmpty()) { 
       return null; 
      } 

      GrantedAuthority runAsAuthority = new SimpleGrantedAuthority(roleName); 
      List<GrantedAuthority> newAuthorities = new ArrayList<GrantedAuthority>(); 
      // Add existing authorities 
      newAuthorities.addAll(authentication.getAuthorities()); 
      // Add the new run-as authority 
      newAuthorities.add(runAsAuthority); 

      return new RunAsUserToken(getKey(), authentication.getPrincipal(), authentication.getCredentials(), 
        newAuthorities, authentication.getClass()); 
     } 
    } 

Questa implementazione cercherà una consuetudine @RunAsRole annotazioni su un metodo protetto (ad es @RunAsRole("ROLE_AUDITOR")) e, se trovato, si aggiungerà l'autorità data (ROLE_AUDITOR in questo caso) all'elenco delle autorità concesse. RunAsRole stesso è solo una semplice annotazione personalizzata.

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface RunAsRole { 
    String value(); 
} 

2) un'istanza della manager:

<bean id="runAsManager" 
    class="org.springframework.security.access.intercept.RunAsManagerImpl"> 
    <property name="key" value="my_run_as_key"/> 
</bean> 

3) Registrati è:

<global-method-security pre-post-annotations="enabled" run-as-manager-ref="runAsManager"> 
    <expression-handler ref="expressionHandler"/> 
</global-method-security> 

4) Esempio di utilizzo in un controllore:

@Controller 
public class TransactionLogController { 

    @PreAuthorize("hasRole('ROLE_REGISTERED_USER')") //Authority needed to access the method 
    @RunAsRole("ROLE_AUDITOR") //Authority added by RunAsManager 
    @RequestMapping(value = "/transactions", method = RequestMethod.GET) //Spring MVC configuration. Not related to security 
    @ResponseBody //Spring MVC configuration. Not related to security 
    public List<Transaction> getTransactionLog(...) { 
    ... //Invoke something in the backend requiring ROLE_AUDITOR 
    { 

    ... //User does not have ROLE_AUDITOR here 
} 

EDIT: Il valore di key in RunAsManagerImpl può essere qualsiasi cosa tu voglia. Ecco l'estratto da Spring docs il suo uso:

Per garantire codice dannoso non crea un RunAsUserToken e presente per l'accettazione garantita dalla RunAsImplAuthenticationProvider, l'hash di una chiave è memorizzato in tutti i token generato. Il RunAsManagerImpl e RunAsImplAuthenticationProvider viene creato nel contesto di fagioli con la stessa chiave:

<bean id="runAsManager" 
    class="org.springframework.security.access.intercept.RunAsManagerImpl"> 

<bean id="runAsAuthenticationProvider" 
    class="org.springframework.security.access.intercept.RunAsImplAuthenticationProvider"> 

Utilizzando la stessa chiave , ogni RunAsUserToken possono essere convalidati è stato creato da un approvato RunAsManagerImpl.RunAsUserToken è immutabile dopo la creazione di per motivi di sicurezza.

+0

Che cosa è esattamente usato per "my_run_as_key"? - Non riesco a capirlo. Probabilmente ho letto la stessa guida che hai citato qui, ma questa chiave non ha alcun senso per me. –

+0

@DanielBo Il valore può essere qualsiasi cosa tu voglia. È fondamentalmente una password. Ho aggiornato la risposta per citare i documenti di Spring sul perché è necessario. – kaqqao