2015-09-26 94 views
2

我在JAX-RS得到的用戶名與SecurityContextHolder資源和工作原理:獲取用戶名和Apache CXF 2.4 JAX-RS和Spring Security的3.2

@Path("/myresource") 
public class MyResoure { 

    @Get 
    public String getUserName() { 
      return SecurityContextHolder.getContext().getAuthentication().getName(); 
    } 
} 

但我想SecurityContext中注入一類字段(編寫JUnit測試)。我嘗試了一些記錄的方式:

With javax.ws.rs.core.SecurityContext我得到一個NullPointerException,因爲securityContext總是null

@Path("/myresource") 
public class MyResoure { 

    @Context 
    private javax.ws.rs.core.SecurityContext securityContext; 

    @Get 
    public String getUserName() { 
     return securityContext.getUserPrincipal().getName(); 
    } 
} 

隨着org.apache.cxf.security.SecurityContext(見Apache CXF documentation)我得到一個NullPointerException,因爲securityContext.getUserPrincipal()總是null

@Path("/myresource") 
public class MyResoure { 

    @Context 
    private org.apache.cxf.security.SecurityContext securityContext; 

    @Get 
    public String getUserName() { 
     return securityContext.getUserPrincipal().getName(); 
    } 
} 

隨着org.apache.cxf.jaxrs.ext.MessageContext(見Apache CXF documentation)我得到一個NullPointerException,因爲messageContext.getSecurityContext().getUserPrincipal()總是null

@Path("/myresource") 
public class MyResoure { 

    @Context 
    private org.apache.cxf.jaxrs.ext.MessageContext messageContext; 

    @Get 
    public String getUserName() { 
     return messageContext.getSecurityContext().getUserPrincipal().getName(); 
    } 
} 

隨着javax.servlet.http.HttpServletRequest我得到了NullPointerException,因爲httpServletRequest.getUserPrincipal()總是null

@Path("/myresource") 
public class MyResoure { 

    @Context 
    private javax.servlet.http.HttpServletRequest httpServletRequest; 

    @Get 
    public String getUserName() { 
     return httpServletRequest.getUserPrincipal().getName(); 
    } 
+1

您是否嘗試過調查SecurityContext中的用戶名設置?您可以創建一個Authentication對象,創建SecurityContext,然後在Junit安裝程序中通過SecurityContextHolder在線程語言環境中設置SecurityContext。 – jitsonfire

回答

2

要與

  • javax.ws.rs.core.SecurityContext獲取用戶名,
  • org.apache.cxf.security.SecurityContext
  • org.apache.cxf.jaxrs.ext.MessageContext
  • javax.servlet.http.HttpServletRequest

我不得不把SecurityContextHolderAwareRequestFilter添加到我的springSecurityFilterChain

Spring配置:

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy"> 
    <security:filter-chain-map path-type="ant"> 
     <security:filter-chain pattern="/**" filters="securityContextPersistenceFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor" /> 
    </security:filter-chain-map> 
</bean> 

使用安全命名空間配置或Java Configuration過濾器默認情況下添加,看到Spring Security documentation

  • 的servlet-API提供 HttpServletRequest提供安全的版本諸如isUserInRole()和getPrincipal()這些方法是通過將SecurityContextHolderAwareRequestFilter bean添加到堆棧。默認爲true。
1

我發現我的JUnit問題的一些解決方案:

  • 設置SecurityContextSecurityContextHolder(見https://stackoverflow.com/a/5703170

    JUnit測試代碼:

    public class MyResourceTest { 
    
        private SecurityContext securityContextMock = mock(SecurityContext.class); 
    
        @Before 
        public void setUp() { 
         SecurityContextHolder.setContext(securityContextMock); 
        } 
    
        @After 
        public void tearDown() { 
         SecurityContextHolder.clearContext(); 
        } 
    } 
    
  • 結束語SecurityContextHolder(見https://stackoverflow.com/a/5702970

    包裝代碼:

    public class MySecurityContextHolder { 
        public SecurityContext getContext() { 
         return SecurityContextHolder.getContext(); 
        } 
    } 
    

    資源代碼:

    @Path("/myresource") 
    public MyResource { 
    
        private MySecurityContextHolder mySecurityContextHolder; 
    
        @Get 
        public String getUserName() { 
         return mySecurityContextHolder.getContext().getAuthentication().getName(); 
        } 
    } 
    
  • 使用SecurityContextHolderStrategy(見SEC-1188

    Spring配置:

    <bean id="myResource" class="MyResource"> 
        <property name="securityContextHolderStrategy" > 
         <bean class="org.springframework.security.context.SecurityContextHolder" factory-method="getContexHolderStrategy"> 
         </bean> 
        </property> 
    </bean> 
    

    資源代碼:

    @Path("/myresource") 
    public MyResource { 
    
        private SecurityContextHolderStrategy securityContextHolderStrategy; 
    
        @Get 
        public String getUserName() { 
         return securityContextHolderStrategy.getContext().getAuthentication().getName(); 
        } 
    } 
    
  • 使用PowerMock(見https://stackoverflow.com/a/5703197/5277820