如何使用 spring-security 设置 JerseyTest?

Posted

技术标签:

【中文标题】如何使用 spring-security 设置 JerseyTest?【英文标题】:How to setup JerseyTest with spring-security? 【发布时间】:2013-11-12 20:15:11 【问题描述】:

我有一个有效的 spring-security 配置,它包装了我基于球衣的 REST 端点并允许方法级访问。

包含快速重现问题所需的一切的示例项目:https://github.com/pulkitsinghal/dummy-rest-api

// Server-Side jersey resource
@GET
@Path("/protected/myendpoint/")
@PreAuthorize("hasRole('DUMMY')")
public String getMyEndpoint()
    return "blah";

但在为受保护端点编写健全性测试时,我遇到了以下异常仅在单元测试中发生

Caused by:
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException:
An Authentication object was not found in the SecurityContext

下面是基于 JerseyTest 的单元测试类的样子:

@Test
public void testProtectedEndpoint() 
    WebResource webResource = resource();
    webResource.addFilter(new HTTPBasicAuthFilter("username", "password"));
    String responseMsg = webResource
                .path("protected/myendpoint/")
                .get(String.class);
    System.out.println(responseMsg);

在为受弹簧安全保护的端点设置JerseyTest 时,有没有其他人遇到过这个问题?有什么办法呢?

我在这里远程看到了一些联系:Spring Test & Security: How to mock authentication?,但我还没有达到可以对该线程中正在发生的事情做出正面或反面的水平。想法?

【问题讨论】:

您能否发布异常的完整堆栈跟踪以及您的 Spring Security 配置?另外,您使用的是哪个版本的 Spring、Spring Security 和 Jersey? 添加了一个在运行单元测试时演示问题的工作示例项目,此处:github.com/pulkitsinghal/dummy-rest-api 这种单元测试是不是在 GrizzlyWebTestContainerFactory 上不管用? 【参考方案1】:

理想情况下,当通过默认的 maven 生命周期运行测试时,我想要一个像 GrizzlyWebTestContainerFactory 这样的单独容器作为测试网络服务器:mvn clean test

但我想,如果没有正确的答案,那么作为测试网络服务器必须使用 ExternalTestContainerFactory 的解决方法:

$ mvn clean package -DskipTests && (nohup foreman start &)
$ mvn -Djersey.test.containerFactory=com.sun.jersey.test.framework.spi.container.external.ExternalTestContainerFactory \
  -Djersey.test.port=5000 \
  -Djersey.test.host=localhost \
  test

注意:对于那些不熟悉 foreman start 的人,只需将其视为 tomcat start 在此用例中用于所有密集用途。

如果测试被破坏并且spring-security不会在外部tomcat上出错,这仍然会阻止签入,所以我想它可以解决。总是去找tomcat/java后台进程的pid,然后杀掉清理,有点烦人。

【讨论】:

【参考方案2】:

JerseyTest 默认在 Grizzly 上运行,并且您的 restful web 服务在 Tomcat 上提供了 spring 安全设置——作为示例。因此,请检查两个 servlet 服务器是否具有相同的设置。

【讨论】:

这很有趣!请帮助我理解,如果我启动 JerseyTest 并在 Grizzly 中启动,为什么 spring-security 配置会在 tomcat 中启动?我很确定 grizzly 负责启动服务器和测试。 如果 grizzly 是您的生产服务器和登台服务器,那很好,不需要那种 tomcat。因此,请检查 JerseyTest 子类的设置是否与生产设置相同。 这可能对你有帮助:github.com/alesaudate/kickstart-springjerseyhibernate/blob/…

以上是关于如何使用 spring-security 设置 JerseyTest?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 ActiveDirectory 与 Spring-Security LDAP 一起使用

Spring-Security OAuth2 设置 - 无法找到 oauth2 命名空间处理程序

如何禁用 spring-security 登录屏幕?

如何使用spring-security通过用户名和密码登录?

如何使用 spring-security 和 jQuery 处理过期会话?

spring-security 如何使用用户名或邮箱登录