2012-07-26 15 views
6

Actualmente estoy usando la seguridad de primavera y las anotaciones @PreAuthorize para asegurar las llamadas al método. Ahora quiero cambiar el token de autenticación para una llamada de método como el run-as authentication replacement de la seguridad de primavera me permite hacer.Cambiar el contexto de seguridad para la llamada al método con spring-security

¿Puedo configurar el reemplazo en una base por método? Por anotación, expresión SpEL .... Si no, ¿sería posible averiguar en el runAsManager qué método se llama? ¿Cómo puedo configurar los atributos de configuración de seguridad para un objeto seguro, en absoluto?

Respuesta

1

Lo resolví implementando mi propio RunAsManager que busca una anotación personalizada en el método invocado y devuelve el token adecuado.

funciona muy bien.

6

He publicado a detailed article sobre la implementación de Run-As junto con @PreAuthorize.

1) Implemente su propio RunAsManager que crea el Authentication para usar durante la ejecución del método en función de cualquier lógica personalizada. El siguiente ejemplo utiliza una anotación personalizada que proporciona la función adicional:

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

Esta aplicación va a buscar una anotación personalizada @RunAsRole en un método protegido (por ejemplo @RunAsRole("ROLE_AUDITOR")) y, si lo encuentra, se agregará la autoridad dada (ROLE_AUDITOR en este caso) a la lista de autoridades otorgadas. RunAsRole es una simple anotación personalizada.

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

2) una instancia del gestor:

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

3) verlo:

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

4) Ejemplo de uso en un controlador:

@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: El valor de key en RunAsManagerImpl puede ser todo lo que desee. Aquí está el extracto de Spring docs sobre su uso:

Para asegurar código malicioso no crea un RunAsUserToken y el presente que para la aceptación garantizada por el RunAsImplAuthenticationProvider, la comprobación de una clave se almacena en todos los tokens generados. El RunAsManagerImpl y RunAsImplAuthenticationProvider se crea en el contexto frijol con la misma clave:

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

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

Al utilizar la misma clave , cada RunAsUserToken se puede validar que fue creado por un aprobado RunAsManagerImpl.El RunAsUserToken es inmutable después de la creación de por razones de seguridad.

+0

¿Para qué se utiliza exactamente "my_run_as_key"? - No puedo resolver esto. Probablemente leí la misma guía que citó aquí, pero esta clave no tiene ningún sentido para mí. –

+0

@DanielBo El valor puede ser lo que quieras. Básicamente es una contraseña. Actualicé la respuesta para citar los documentos de Spring sobre por qué es necesario. – kaqqao

Cuestiones relacionadas