问题描述
我正在尝试通过进行休息调用(使用改造)为我的 web 应用程序创建自动化的、端到端的测试。 我们的休息电话受到 spring 安全保护,所以我必须先登录。
据我所知,我需要使用用户/密码调用 /j_spring_security_check,获取返回的“Set-cookie”响应标头并将其设置为我执行的每次休息调用时的“Cookie”请求标头。
似乎我对 spring 登录“页面”的调用是成功的,因为我们已经实现了一个 ApplicationListener,它记录了每次成功的登录尝试,但是,从调用 j_spring_security_check 返回的响应状态为 200(应该是 302,因为应用程序在成功后重定向login) 并且响应的正文是登录页面本身。
我究竟做错了什么?
登录改造界面:
@FormUrlEncoded
@POST("/j_spring_security_check")
Response basicLogin(@Field("user") String user, @Field("password") String pwd);
调用spring登录的代码:
public static void login(String user, String pwd) {
PortalLoginService loginService = PortalRestAdapter.getInstance().createLoginService();
Response response = loginService.basicLogin(user, pwd);
String setCookieHeader = getSetCookieHeader(response.getHeaders());
AuthCookieInterceptor.getInstance().setSessionId(setCookieHeader);
}
private static String getSetCookieHeader(List<Header> headers) {
for (Header header : headers) {
if (SET_COOKIE_HEADER_NAME.equals(header.getName())) {
return header.getValue();
}
}
return null;
}
AuthCookieInterceptor 拦截方法的代码:
@Override
public void intercept(RequestFacade requestFacade) {
if (sessionId != null) {
requestFacade.addHeader("Cookie", sessionId);
}
}
其余的适配器初始化:
restAdapter = new RestAdapter.Builder()
.setRequestInterceptor(AuthCookieInterceptor.getInstance())
.setEndpoint(PORTAL_URL)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
所以基本上我正在调用登录,并在我发出的每个请求上设置从登录响应返回的会话 ID(使用请求拦截器)
非常感谢
1楼
您需要更改传递的参数的名称, j_spring_security_check 需要 j_username 和 j_password 而不是您的
Response basicLogin(@Field("user") String user, @Field("password") String pwd);
此外,因为在此调用的情况下,spring 框架会返回一个 html 响应(请记住,我们正在对 servlet 执行 POST),因此我们需要设置转换器,因此您需要执行以下操作:
SimpleXMLConverter converter = new SimpleXMLConverter();
RestAdapter adapter = builder.setLogLevel(RestAdapter.LogLevel.FULL).setConverter(converter).build();
然后是这样一个简单的调用:
Response response = LoginClient.getService().login("john", "john1");
从响应对象中,您可以获得您可能需要的任何信息
2楼
我已经解决了这个难题。 首先要授权用户,您需要将“用户”替换为“用户名”
@FormUrlEncoded
@POST("/login")
Response autorizeMethod(@Field("username") String user, @Field("password") String pwd);
然后在改造中禁用自动重定向
val client=OkHttpClient.Builder().followRedirects(false).build()
Retrofit.Builder()
.baseUrl("http://localhost:8080")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()