2011-03-23 14 views
10

he definido este método en mi controlador MVC primavera:¿Cómo JUnit prueba una anotación @PreAuthorize y su EL de resorte especificado por un controlador MVC de resorte?

@RequestMapping(value = "{id}/content", method=RequestMethod.POST) 
@PreAuthorize("principal.user.userAccount instanceof T(com.anonym.model.identity.PedagoAccount) AND principal.user.userAccount.userId == #object.pedago.userId AND #form.id == #object.id") 
public String modifyContent(@PathVariable("id") Project object, @Valid @ModelAttribute("form") ProjectContentForm form) { 
    .... 
} 

Luego, en mi prueba JUnit me gustaría llamar a este método y asegurarse de que la condición se verifica preauthorize. Pero cuando configuro el usuario principal en mi prueba JUnit con una cuenta incorrecta, no hay ningún error y el método se completa. Parece que la anotación está anulada.
Pero cuando llamo a este método de una manera normal (sin pruebas), se verifica la autorización previa.

Si es posible, ¿cómo probar esta anotación en una prueba junit y cómo atrapar la excepción si arroja una?

Gracias,
Nicolas

+0

Solo una nota para los demás que usan "principal" en PreAuthorize, esto fallará con una excepción de nullpointerexcpetion y no activará una reautorización a menos que incluya algo similar a isAuthenticated() en la anotación PreAuthorize o en security.xml – chrismarx

Respuesta

15

Desde que desea probar características implementadas a través de la primavera AOP, es necesario utilizar Spring TestContext marco para ejecutar las pruebas en contra de contexto de aplicación.

a continuación, crear una prueba de base con la configuración de seguridad mínima:

abstract-security-test.xml:

<security:authentication-manager alias="authenticationManager"> 
    <security:authentication-provider user-service-ref = "userService" /> 
</security:authentication-manager> 

<security:global-method-security pre-post-annotations="enabled" /> 

<bean id = "userService" class = "..." /> 

AbstractSecurityTest.java:

@ContextConfiguration("abstract-security-test.xml") 
abstract public class AbstractSecurityTest { 
    @Autowired 
    private AuthenticationManager am; 

    @After 
    public void clear() { 
     SecurityContextHolder.clearContext(); 
    } 

    protected void login(String name, String password) { 
     Authentication auth = new UsernamePasswordAuthenticationToken(name, password); 
     SecurityContextHolder.getContext().setAuthentication(am.authenticate(auth)); 
    } 
} 

Ahora usted puede utilizarlo en sus pruebas:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(...) 
public class CreatePostControllerSecurityTest extends AbstractSecurityTest { 
    ... 

    @Test 
    @ExpectedException(AuthenticationCredentialsNotFoundException.class) 
    public void testNoAuth() { 
     controller.modifyContent(...); 
    } 

    @Test 
    @ExpectedException(AccessDeniedException.class) 
    public void testAccessDenied() { 
     login("userWithoutAccessRight", "..."); 
     controller.modifyContent(...); 
    } 

    @Test 
    public void testAuthOK() { 
     login("userWithAccessRight", "..."); 
     controller.modifyContent(...); 
    } 
} 
+0

Gracias usted, funciona bien para la autenticación, pero si desea probar todo el EL de Spring definido en la anotación PreAuthorize, ¿cómo lo hago?
Nico

+0

Gracias, funciona bien para la autenticación, pero si quiero probar todo el EL de Spring definido en la anotación PreAuthorize, ¿cómo lo hago? Me refiero a cómo verificar principal.user.userAccount.userId == # object.pedago.userId AND # form.id == # object.id donde #object y #form designan variables del método modifyContent. ¿Hay alguna excepción para atrapar una seguridad sin verificar Spring EL? – Nico

+0

@Nico: actualizado. – axtavt

Cuestiones relacionadas