2015-09-26 92 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