2014-04-15 99 views
0

我控制器:春季安全@ PreAuthorize- ProviderNotFoundException異常

@RestController 
public class CheckPermissionContr { 

    @PreAuthorize("hasRole('ROLE_USER')") 
    @RequestMapping(value = "/permission", method = RequestMethod.GET) 
    public String checkPermission(@RequestParam("id") UUID id) { 

當我把它從單元測試,如:

@RunWith(SpringJUnit4ClassRunner.class) 
    @WebAppConfiguration 
    @ContextConfiguration("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml") 
    public class CheckPermissionContrTest { 

    @SuppressWarnings("SpringJavaAutowiringInspection") 
    @Autowired 
    protected WebApplicationContext wac; 

    private MockMvc mockMvc; 


    @Before 
    public void init() { 

     MockitoAnnotations.initMocks(this); 
     BasicConfigurator.configure(); 

     this.mockMvc = webAppContextSetup(wac).build(); 

     final GeneralAuthentication authen = mock(GeneralAuthentication.class); 
     user = mock(User.class); 

     when(user.getId()).thenReturn(UUID.randomUUID()); 

     final GrantedAuthority mockAuth = mock(GrantedAuthority.class); 
     doReturn("ROLE_USER").when(mockAuth).getAuthority(); 
     Collection<GrantedAuthority> authority = Collections.singleton(mockAuth); 

     doReturn(authority).when(authen).getAuthorities(); 
     when(authen.getPrincipal()).thenReturn(user); 



     final SecurityContext secContext = mock(SecurityContext.class); 
     when(secContext.getAuthentication()).thenReturn(authen); 
     SecurityContextHolder.setContext(secContext); 

     } 

    @Test 
    public void testCheckPermission() throws Exception { 
     mockMvc.perform(get("/permission.json").param("id", id.toString())).andExpect(status().isOk()).andDo(print()); 

當我運行測試:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for com.XXXXX.GeneralAuthentication$$EnhancerByMockitoWithCGLIB$$6db1e4cf 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:734) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) 
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:62) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) 
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:170) 
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:137) 
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:141) 
    at com.XXXXX.CheckPermissionContrTest.testCheckPermission(CheckPermissionContrTest.java:121) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) 
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) 
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
Caused by: org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for com.XXXXX.GeneralAuthentication$$EnhancerByMockitoWithCGLIB$$6db1e4cf 
    at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) 
    at org.springframework.security.config.method.GlobalMethodSecurityBeanDefinitionParser$AuthenticationManagerDelegator.authenticate(GlobalMethodSecurityBeanDefinitionParser.java:433) 
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.authenticateIfRequired(AbstractSecurityInterceptor.java:316) 
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:202) 
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:60) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644) 
    at com.XXXXX.CheckPermissionContr$$EnhancerBySpringCGLIB$$f974fa1c.checkPermission(<generated>) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHand 

但當我用@Secured("ROLE_USER")替換@PreAuthorize一切順利。

通過.xml蘊涵:

WEB-INF/MVC-調度-servlet.xml中

 <import resource="spring-security.xml"/> 

內部彈簧的security.xml

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

<security:http use-expressions="true" auto-config="false" entry-point-ref="restEntryPoint"> 
    <security:intercept-url pattern="/*"/> 
</security:http> 

<bean id="auhProvider" class="com.XXXXX.AuhProvider"> 
    <constructor-arg name="userRepo" ref="userRepo"/> 

</bean> 

<security:authentication-manager alias="manager"> 
    <security:authentication-provider ref="auhProvider"> 

    </security:authentication-provider> 
</security:authentication-manager> 

附加代碼:

@Override 
    public boolean supports(Class<?> aClass) { 

     return aClass.isAssignableFrom(GeneralAuthentication.class); 
    } 
+0

你可以發佈'com.XXXXX.AuhProvider'的'supports()'方法嗎? – zeroflagL

+0

@zeroflagL我現在這樣做。 – user902691

回答

1

com.XXXXX.AuhProvider僅支持GeneralAuthentication.class類型的對象。既然你模擬authen它不再有這個類,而是com.XXXXX.GeneralAuthentication$$EnhancerByMockitoWithCGLIB$$6db1e4cf

support方法測試必須是周圍的其他方法:這意味着

GeneralAuthentication.class.isAssignableFrom(aClass) 

「是ACLASS GeneralAuthentication.class或它的子類型」。