2011-03-23 63 views
10

我在我的Spring MVC控制器定义这个方法:如何JUnit测试@PreAuthorize注释及其由弹簧MVC控制器指定的弹簧EL?

@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) { 
    .... 
} 

然后在我的JUnit测试我想调用此方法,并确保预授权条件进行验证。但是当我在一个坏帐户的JUnit测试中设置用户主体时,没有错误并且方法完成。似乎这个注释被绕过了。
但是,当我以正常方式(而不是测试)调用此方法时,PreAuthorize会被验证。

如果可能的话,如何在junit测试中测试这个注解以及如何在抛出异常时捕获异常?

谢谢
萨科

+0

只需在PreAuthorize中使用“principal”的其他人员注释,此操作将失败并显示nullpointerexcpetion,并且不会触发重新授权,除非您在PreAuthorize批注中或security.xml中包含isAuthenticated()的效果。 – chrismarx 2014-02-28 15:34:22

回答

15

既然你想测试通过的Spring AOP实现的功能,你需要使用Spring TestContext框架来运行针对应用程序上下文测试。

然后创建具有最低限度的安全配置的基础测试:

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

现在你可以在你的测试中使用它:

@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

你,对于身份验证来说工作正常,但是如果要测试PreAuthorize注释中定义的整个Spring EL,我该怎么做?
Nico 2011-03-23 12:49:56

+0

谢谢,它对身份验证很有效,但如果我想测试PreAuthorize注释中定义的整个Spring EL,我该怎么做?我的意思是如何验证principal.user.userAccount.userId ==#object.pedago.userId AND#form.id ==#object.id其中#object和#form指定modifyContent方法的变量。有没有什么例外可以找到未经验证的安全性Spring EL? – Nico 2011-03-23 12:55:47

+0

@Nico:已更新。 – axtavt 2011-03-23 13:17:21