当前位置: 代码迷 >> java >> 无法获得正确的会话 ID 以通过改造登录 Spring Security
  详细解决方案

无法获得正确的会话 ID 以通过改造登录 Spring Security

热度:69   发布时间:2023-07-26 14:35:43.0

我正在尝试通过进行休息调用(使用改造)为我的 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(使用请求拦截器)

非常感谢

您需要更改传递的参数的名称, 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");

从响应对象中,您可以获得您可能需要的任何信息

我已经解决了这个难题。 首先要授权用户,您需要将“用户”替换为“用户名”

@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()
  相关解决方案