使用 Apache CXF 2.4 JAX-RS 和 Spring Security 3.2 获取用户名
Get user name with Apache CXF 2.4 JAX-RS and Spring Security 3.2
我使用 SecurityContextHolder
在我的 JAX-RS 资源中获取了用户名并且有效:
@Path("/myresource")
public class MyResoure {
@Get
public String getUserName() {
return SecurityContextHolder.getContext().getAuthentication().getName();
}
}
但我想将 SecurityContext 注入 class 字段(以编写 JUnit 测试)。我尝试了一些记录在案的方法:
使用 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();
}
我找到了一些解决 JUnit 问题的方法:
在 SecurityContextHolder
中设置 SecurityContext
(参见 )
JUnit测试代码:
public class MyResourceTest {
private SecurityContext securityContextMock = mock(SecurityContext.class);
@Before
public void setUp() {
SecurityContextHolder.setContext(securityContextMock);
}
@After
public void tearDown() {
SecurityContextHolder.clearContext();
}
}
环绕 SecurityContextHolder
(参见 )
包装代码:
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(参见 )
获取用户名
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 the filter is added by default, see Spring Security documentation:
- servlet-api-provision Provides versions of HttpServletRequest security methods such as isUserInRole() and getPrincipal() which are implemented by adding a SecurityContextHolderAwareRequestFilter bean to the stack. Defaults to true.
我使用 SecurityContextHolder
在我的 JAX-RS 资源中获取了用户名并且有效:
@Path("/myresource")
public class MyResoure {
@Get
public String getUserName() {
return SecurityContextHolder.getContext().getAuthentication().getName();
}
}
但我想将 SecurityContext 注入 class 字段(以编写 JUnit 测试)。我尝试了一些记录在案的方法:
使用 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();
}
我找到了一些解决 JUnit 问题的方法:
在
SecurityContextHolder
中设置SecurityContext
(参见 )JUnit测试代码:
public class MyResourceTest { private SecurityContext securityContextMock = mock(SecurityContext.class); @Before public void setUp() { SecurityContextHolder.setContext(securityContextMock); } @After public void tearDown() { SecurityContextHolder.clearContext(); } }
环绕
SecurityContextHolder
(参见 )包装代码:
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(参见 )
获取用户名
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 the filter is added by default, see Spring Security documentation:
- servlet-api-provision Provides versions of HttpServletRequest security methods such as isUserInRole() and getPrincipal() which are implemented by adding a SecurityContextHolderAwareRequestFilter bean to the stack. Defaults to true.