2017-10-31 21 views
1

내가 좋아하는 방법으로 많은 @RestController의이 (사용자 bean-spel로 @PreAuthorize가 유효한지 테스트하는 방법은 무엇입니까?

@PreAuthorize("@myBean.myMethod(#param1, #param2)") 
public void foo(String param1, Long param2) {} 

그리고 어딘가

@Component 
public class MyBean { 
    public boolean myMethod(String param1, Long param2) { 

     return importantSecurityCheck(); 
    } 
} 

그것은 아주 잘, 하지만 리팩토링 후 가능 바보 같은 버그를 방지 할 작동을 같은 때문에 지금까지는 스프링이 메소드가 호출 될 때까지 에러를 감지하지 못한다.) 그래서 내 생각은 표현식이 유효한지 검사 할 테스트를 작성하는 것이었다 (예 : 매개 변수의 유형과 이름이 유효 함).

나는 이런 식으로 뭔가하려고 노력 :

@Test 
public void checkSecurityExpressions() { 
Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(RestController.class); 

    beansWithAnnotation.forEach((name, bean) -> { 
     Method[] methods = AopUtils.getTargetClass(bean).getMethods(); 

     for (Method method : methods) { 
      PreAuthorize annotation = method.getAnnotation(PreAuthorize.class); 

      if (annotation != null) { 

       String securityExpression = annotation.value(); 

       System.out.println(securityExpression); 
      } 

     } 
    }); 
} 

잘 표현을 발견,하지만 난 (처음에도 @하지 않고, 보안 컨텍스트없이) 간단한 식으로 일을 찾은 모든 ExpressionParser 예.

정확성을 확인하는 방법은 무엇입니까? 아니면이 문제에 대한 더 나은 해결책이 있을까요?

답변

0

나는 최근에 answer another stack overflow question과 같은 테스트 케이스를 작성해야했습니다.

을 감안할 때 :

public class Foo { 

    public boolean isOk(String param) { 
     return "good".equals(param); 
    } 

    @PreAuthorize("@foo.isOk(#param1)") 
    public String bar(String param1) { 
     return "authOk"; 
    } 

} 

및 테스트 @Configuration 클래스 extends GlobalAuthenticationConfigurerAdapter 그 :

@Override 
public void init(AuthenticationManagerBuilder auth) throws Exception { 
    auth.inMemoryAuthentication() 
     .withUser("foo").password("bar").roles("admin"); 
} 

다음 :

@Autowired 
private Foo foo; 

@Test 
public void test() { 
    SecurityContext ctx = SecurityContextHolder.createEmptyContext(); 
    ctx.setAuthentication(new UsernamePasswordAuthenticationToken("foo", "bar")); 
    SecurityContextHolder.setContext(ctx); 
    assertThat(foo.bar("good")).isEqualTo("authOk"); 
    try { 
     foo.bar("bad"); 
     fail("Expected AccessDeniedException"); 
    } 
    catch (AccessDeniedException e) { 
     // expected 
    } 
} 

@PreAuthorize SpEL을 유효성을 검사합니다.